23#include "clang/Config/config.h"
26#include "llvm/ADT/DenseSet.h"
27#include "llvm/ADT/SetVector.h"
28#include "llvm/ADT/SmallPtrSet.h"
29#include "llvm/ADT/StringExtras.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/raw_ostream.h"
34#if CLANG_ENABLE_OBJC_REWRITER
57 BLOCK_NEEDS_FREE = (1 << 24),
58 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
60 BLOCK_IS_GC = (1 << 27),
62 BLOCK_HAS_DESCRIPTOR = (1 << 29)
72 const char *MainFileStart, *MainFileEnd;
75 std::string InFileName;
76 std::unique_ptr<raw_ostream> OutFile;
81 Expr *GlobalConstructionExp;
82 unsigned RewriteFailedDiag;
83 unsigned GlobalBlockRewriteFailedDiag;
85 unsigned NumObjCStringLiterals;
86 VarDecl *ConstantStringClassReference;
92 unsigned TryFinallyContainsReturnDiag;
144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
148 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
154 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
157 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
163 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
167 bool SilenceRewriteMacroWarning;
168 bool GenerateLineInfo;
169 bool objc_impl_method;
171 bool DisableReplaceStmt;
172 class DisableReplaceStmtScope {
173 RewriteModernObjC &R;
177 DisableReplaceStmtScope(RewriteModernObjC &R)
178 : R(R), SavedValue(R.DisableReplaceStmt) {
179 R.DisableReplaceStmt =
true;
181 ~DisableReplaceStmtScope() {
182 R.DisableReplaceStmt = SavedValue;
188 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
194 if (!
Class->isThisDeclarationADefinition()) {
195 RewriteForwardClassDecl(
D);
199 ObjCInterfacesSeen.push_back(Class);
205 if (!Proto->isThisDeclarationADefinition()) {
206 RewriteForwardProtocolDecl(
D);
216 if (FDecl->isThisDeclarationADefinition() &&
218 !FDecl->isTopLevelDeclInObjCContainer()) {
219 FunctionDefinitionsSeen.push_back(FDecl);
223 HandleTopLevelSingleDecl(*I);
228 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
231 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
232 RewriteBlockPointerDecl(TD);
233 else if (TD->getUnderlyingType()->isFunctionPointerType())
234 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
236 RewriteObjCQualifiedInterfaceTypes(TD);
241 void HandleTopLevelSingleDecl(
Decl *
D);
242 void HandleDeclInMainFile(
Decl *
D);
243 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
245 bool silenceMacroWarn,
bool LineInfo);
247 ~RewriteModernObjC()
override {}
249 void HandleTranslationUnit(
ASTContext &C)
override;
251 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
256 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
258 Stmt *ReplacingStmt = ReplacedNodes[Old];
262 if (DisableReplaceStmt)
274 llvm::raw_string_ostream S(SStr);
279 ReplacedNodes[Old] = New;
282 if (SilenceRewriteMacroWarning)
289 bool InsertAfter =
true) {
291 if (!
Rewrite.InsertText(
Loc, Str, InsertAfter) ||
292 SilenceRewriteMacroWarning)
295 Diags.
Report(Context->getFullLoc(
Loc), RewriteFailedDiag);
301 if (!
Rewrite.ReplaceText(Start, OrigLength, Str) ||
302 SilenceRewriteMacroWarning)
305 Diags.
Report(Context->getFullLoc(Start), RewriteFailedDiag);
310 void RewriteInclude();
311 void RewriteLineDirective(
const Decl *
D);
313 std::string &LineString);
317 const std::string &typedefString);
318 void RewriteImplementations();
323 void RewriteImplementationDecl(
Decl *Dcl);
326 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
328 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
337 void RewriteBlockPointerType(std::string& Str,
QualType Type);
338 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
340 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
341 void RewriteTypeOfDecl(
VarDecl *VD);
342 void RewriteObjCQualifiedInterfaceTypes(
Expr *
E);
347 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
368 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
373 void ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV, std::string &Result);
375 void ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV, std::string &Result);
377 void ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV, std::string &Result);
380 QualType SynthesizeBitfieldGroupStructType(
388 void RewriteBlockPointerDecl(
NamedDecl *VD);
389 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
395 std::string &Result);
397 void RewriteObjCFieldDecl(
FieldDecl *fieldDecl, std::string &Result);
399 bool &IsNamedDefinition);
400 void RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
401 std::string &Result);
403 bool RewriteObjCFieldDeclType(
QualType &
Type, std::string &Result);
406 std::string &Result);
408 void Initialize(
ASTContext &context)
override;
427 void SynthCountByEnumWithState(std::string &buf);
428 void SynthMsgSendFunctionDecl();
429 void SynthMsgSendSuperFunctionDecl();
430 void SynthMsgSendStretFunctionDecl();
431 void SynthMsgSendFpretFunctionDecl();
432 void SynthMsgSendSuperStretFunctionDecl();
433 void SynthGetClassFunctionDecl();
434 void SynthGetMetaClassFunctionDecl();
435 void SynthGetSuperClassFunctionDecl();
436 void SynthSelGetUidFunctionDecl();
437 void SynthSuperConstructorFunctionDecl();
440 template<
typename MethodIterator>
441 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
442 MethodIterator MethodEnd,
443 bool IsInstanceMethod,
446 std::string &Result);
448 std::string &Result);
450 std::string &Result);
451 void RewriteClassSetupInitHook(std::string &Result);
453 void RewriteMetaDataIntoBuffer(std::string &Result);
454 void WriteImageInfo(std::string &Result);
456 std::string &Result);
457 void RewriteCategorySetupInitHook(std::string &Result);
461 std::string &Result);
465 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
466 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
468 const std::string &Tag);
469 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i, StringRef funcName,
470 const std::string &Tag);
471 std::string SynthesizeBlockImpl(
BlockExpr *CE,
const std::string &Tag,
472 const std::string &Desc);
473 std::string SynthesizeBlockDescriptor(
const std::string &DescTag,
474 const std::string &ImplTag,
int i,
475 StringRef funcName,
unsigned hasCopy);
479 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
485 void WarnAboutReturnGotoStmts(
Stmt *S);
487 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
490 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
491 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
492 void GetBlockDeclRefExprs(
Stmt *S);
493 void GetInnerBlockDeclRefExprs(
Stmt *S,
495 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
499 bool isTopLevelBlockPointerType(
QualType T) {
500 return isa<BlockPointerType>(T);
506 bool convertBlockPointerToFunctionPointer(
QualType &T) {
507 if (isTopLevelBlockPointerType(T)) {
509 T = Context->getPointerType(BPT->getPointeeType());
515 bool convertObjCTypeToCStyleType(
QualType &T);
517 bool needToScanForQualifiers(
QualType T);
519 QualType getConstantStringStructType();
522 void convertToUnqualifiedObjCType(
QualType &T) {
524 bool isConst =
T.isConstQualified();
525 T = isConst ? Context->getObjCIdType().withConst()
526 : Context->getObjCIdType();
529 T = Context->getObjCClassType();
536 T = Context->getPointerType(T);
546 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
548 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
549 OCT == Context->getCanonicalType(Context->getObjCClassType()))
553 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
554 PT->getPointeeType()->isObjCQualifiedIdType())
560 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
561 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
562 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
563 const char *&RParen);
565 void QuoteDoublequotes(std::string &From, std::string &To) {
566 for (
unsigned i = 0; i < From.length(); i++) {
576 bool variadic =
false) {
577 if (result == Context->getObjCInstanceType())
578 result = Context->getObjCIdType();
581 return Context->getFunctionType(result, args, fpi);
588 return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue,
Kind,
E,
nullptr,
593 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
595 Selector LoadSel = Context->Selectors.getSelector(0, &II);
600 QualType StrType = Context->getConstantArrayType(
601 Context->CharTy, llvm::APInt(32, Str.size() + 1),
nullptr,
602 ArraySizeModifier::Normal, 0);
603 return StringLiteral::Create(*Context, Str, StringLiteralKind::Ordinary,
609void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
612 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
613 for (
const auto &I : fproto->param_types())
614 if (isTopLevelBlockPointerType(I)) {
616 RewriteBlockPointerDecl(
D);
622void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
624 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
628static bool IsHeaderFile(
const std::string &
Filename) {
629 std::string::size_type DotPos =
Filename.rfind(
'.');
631 if (DotPos == std::string::npos) {
636 std::string Ext =
Filename.substr(DotPos + 1);
639 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
642RewriteModernObjC::RewriteModernObjC(std::string inFile,
643 std::unique_ptr<raw_ostream> OS,
646 bool silenceMacroWarn,
bool LineInfo)
647 : Diags(
D), LangOpts(LOpts), InFileName(inFile), OutFile(
std::move(OS)),
648 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
649 IsHeader = IsHeaderFile(inFile);
651 "rewriting sub-expression within a macro (may not be correct)");
654 GlobalBlockRewriteFailedDiag = Diags.
getCustomDiagID(DiagnosticsEngine::Warning,
655 "rewriting block literal declared in global scope is not implemented");
658 DiagnosticsEngine::Warning,
659 "rewriter doesn't support user-specified control flow semantics "
660 "for @try/@finally (code may not execute properly)");
664 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
666 bool SilenceRewriteMacroWarning,
bool LineInfo) {
667 return std::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
668 LOpts, SilenceRewriteMacroWarning,
672void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
674 SM = &Context->getSourceManager();
675 TUDecl = Context->getTranslationUnitDecl();
676 MsgSendFunctionDecl =
nullptr;
677 MsgSendSuperFunctionDecl =
nullptr;
678 MsgSendStretFunctionDecl =
nullptr;
679 MsgSendSuperStretFunctionDecl =
nullptr;
680 MsgSendFpretFunctionDecl =
nullptr;
681 GetClassFunctionDecl =
nullptr;
682 GetMetaClassFunctionDecl =
nullptr;
683 GetSuperClassFunctionDecl =
nullptr;
684 SelGetUidFunctionDecl =
nullptr;
685 CFStringFunctionDecl =
nullptr;
686 ConstantStringClassReference =
nullptr;
687 NSStringRecord =
nullptr;
688 CurMethodDef =
nullptr;
689 CurFunctionDef =
nullptr;
690 GlobalVarDecl =
nullptr;
691 GlobalConstructionExp =
nullptr;
692 SuperStructDecl =
nullptr;
693 ProtocolTypeDecl =
nullptr;
694 ConstantStringDecl =
nullptr;
696 SuperConstructorFunctionDecl =
nullptr;
697 NumObjCStringLiterals = 0;
698 PropParentMap =
nullptr;
699 CurrentBody =
nullptr;
700 DisableReplaceStmt =
false;
701 objc_impl_method =
false;
704 MainFileID =
SM->getMainFileID();
705 llvm::MemoryBufferRef MainBuf =
SM->getBufferOrFake(MainFileID);
706 MainFileStart = MainBuf.getBufferStart();
707 MainFileEnd = MainBuf.getBufferEnd();
709 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
716void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *
D) {
727 if (
Loc.isInvalid())
return;
731 RewriteFunctionDecl(FD);
732 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(
D)) {
734 if (FVD->getName() ==
"_NSConstantStringClassReference") {
735 ConstantStringClassReference = FVD;
739 RewriteCategoryDecl(CD);
741 if (PD->isThisDeclarationADefinition())
742 RewriteProtocolDecl(PD);
746 DIEnd = LSD->decls_end();
749 if (!IFace->isThisDeclarationADefinition()) {
753 if (isa<ObjCInterfaceDecl>(*DI) &&
754 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
755 StartLoc == (*DI)->getBeginLoc())
761 }
while (DI != DIEnd);
762 RewriteForwardClassDecl(DG);
767 ObjCInterfacesSeen.push_back(IFace);
774 if (!Proto->isThisDeclarationADefinition()) {
778 if (isa<ObjCProtocolDecl>(*DI) &&
779 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
780 StartLoc == (*DI)->getBeginLoc())
786 }
while (DI != DIEnd);
787 RewriteForwardProtocolDecl(DG);
792 HandleTopLevelSingleDecl(*DI);
797 if (
SM->isWrittenInMainFile(
Loc))
798 return HandleDeclInMainFile(
D);
805void RewriteModernObjC::RewriteInclude() {
807 StringRef MainBuf =
SM->getBufferData(MainFileID);
808 const char *MainBufStart = MainBuf.begin();
809 const char *MainBufEnd = MainBuf.end();
810 size_t ImportLen = strlen(
"import");
813 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
814 if (*BufPtr ==
'#') {
815 if (++BufPtr == MainBufEnd)
817 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
818 if (++BufPtr == MainBufEnd)
820 if (!strncmp(BufPtr,
"import", ImportLen)) {
824 ReplaceText(ImportLoc, ImportLen,
"include");
833 Result +=
"OBJC_IVAR_$_";
844 std::string IvarOffsetName;
846 ObjCIvarBitfieldGroupOffset(
D, IvarOffsetName);
848 WriteInternalIvarName(ClassDecl,
D, IvarOffsetName);
850 std::string S =
"(*(";
853 IvarT = GetGroupRecordTypeForObjCIvarBitfield(
D);
860 auto *CDecl = cast<ObjCContainerDecl>(
D->getDeclContext());
863 CDecl = CatDecl->getClassInterface();
864 std::string RecName = std::string(CDecl->getName());
866 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
868 &Context->Idents.get(RecName));
869 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
870 unsigned UnsignedIntSize =
871 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
872 Expr *
Zero = IntegerLiteral::Create(*Context,
873 llvm::APInt(UnsignedIntSize, 0),
875 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
880 &Context->Idents.get(
D->getNameAsString()),
885 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
886 IvarT = Context->getDecltypeType(ME, ME->
getType());
889 convertObjCTypeToCStyleType(IvarT);
890 QualType castT = Context->getPointerType(IvarT);
891 std::string TypeString(castT.
getAsString(Context->getPrintingPolicy()));
896 S +=
"((char *)self + ";
899 if (
D->isBitField()) {
901 S +=
D->getNameAsString();
920 static bool objcGetPropertyDefined =
false;
921 static bool objcSetPropertyDefined =
false;
926 InsertText(startLoc,
"// ");
927 const char *startBuf =
SM->getCharacterData(startLoc);
928 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
929 const char *semiBuf = strchr(startBuf,
';');
930 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
941 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
944 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
945 bool GenGetProperty =
946 !(Attributes & ObjCPropertyAttribute::kind_nonatomic) &&
947 (Attributes & (ObjCPropertyAttribute::kind_retain |
948 ObjCPropertyAttribute::kind_copy));
950 if (GenGetProperty && !objcGetPropertyDefined) {
951 objcGetPropertyDefined =
true;
953 Getr =
"\nextern \"C\" __declspec(dllimport) "
954 "id objc_getProperty(id, SEL, long, bool);\n";
961 if (GenGetProperty) {
974 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
976 std::string ParamStr =
977 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
980 if (FT->isVariadic()) {
981 if (FT->getNumParams())
990 Getr +=
"return (_TYPE)";
991 Getr +=
"objc_getProperty(self, _cmd, ";
992 RewriteIvarOffsetComputation(OID, Getr);
996 Getr +=
"return " + getIvarAccessString(OID);
998 InsertText(startGetterSetterLoc, Getr);
1002 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1007 bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain |
1008 ObjCPropertyAttribute::kind_copy);
1009 if (GenSetProperty && !objcSetPropertyDefined) {
1010 objcSetPropertyDefined =
true;
1012 Setr =
"\nextern \"C\" __declspec(dllimport) "
1013 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1021 if (GenSetProperty) {
1022 Setr +=
"objc_setProperty (self, _cmd, ";
1023 RewriteIvarOffsetComputation(OID, Setr);
1027 if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
1031 if (Attributes & ObjCPropertyAttribute::kind_copy)
1037 Setr += getIvarAccessString(OID) +
" = ";
1041 InsertText(startGetterSetterLoc, Setr);
1045 std::string &typedefString) {
1046 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1048 typedefString +=
"\n";
1049 typedefString +=
"#define _REWRITER_typedef_";
1051 typedefString +=
"\n";
1052 typedefString +=
"typedef struct objc_object ";
1055 typedefString +=
";\ntypedef struct {} _objc_exc_";
1057 typedefString +=
";\n#endif\n";
1060void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1061 const std::string &typedefString) {
1063 const char *startBuf =
SM->getCharacterData(startLoc);
1064 const char *semiPtr = strchr(startBuf,
';');
1066 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1069void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1070 std::string typedefString;
1073 if (I ==
D.begin()) {
1077 typedefString +=
"// @class ";
1079 typedefString +=
";";
1081 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1084 HandleTopLevelSingleDecl(*I);
1087 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1090void RewriteModernObjC::RewriteForwardClassDecl(
1092 std::string typedefString;
1093 for (
unsigned i = 0; i <
D.size(); i++) {
1096 typedefString +=
"// @class ";
1098 typedefString +=
";";
1100 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1102 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(
D[0]), typedefString);
1105void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1113 if (
SM->getExpansionLineNumber(LocEnd) >
1114 SM->getExpansionLineNumber(LocStart)) {
1115 InsertText(LocStart,
"#if 0\n");
1116 ReplaceText(LocEnd, 1,
";\n#endif\n");
1118 InsertText(LocStart,
"// ");
1125 ReplaceText(
Loc, 0,
"// ");
1134 ReplaceText(LocStart, 1,
"/** ");
1138 ReplaceText(LocStart, 0,
"// ");
1145 RewriteMethodDeclaration(I);
1147 RewriteMethodDeclaration(I);
1151 strlen(
"@end"),
"/* @end */\n");
1159 ReplaceText(LocStart, 0,
"// ");
1162 RewriteMethodDeclaration(I);
1164 RewriteMethodDeclaration(I);
1170 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1173 const char *startBuf =
SM->getCharacterData(LocStart);
1174 const char *endBuf =
SM->getCharacterData(LocEnd);
1175 for (
const char *p = startBuf; p < endBuf; p++) {
1176 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1178 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1181 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1183 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1189void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1192 llvm_unreachable(
"Invalid SourceLocation");
1194 ReplaceText(LocStart, 0,
"// ");
1201 llvm_unreachable(
"Invalid SourceLocation");
1203 ReplaceText(LocStart, 0,
"// ");
1206void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1226 ResultStr +=
T.getAsString(Context->getPrintingPolicy());
1231 std::string &ResultStr) {
1234 ResultStr +=
"\nstatic ";
1235 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1239 std::string NameStr;
1257 int len = selString.size();
1258 for (
int i = 0; i < len; i++)
1259 if (selString[i] ==
':')
1261 NameStr += selString;
1264 MethodInternalNames[OMD] = NameStr;
1265 ResultStr += NameStr;
1272 QualType selfTy = Context->getObjCInterfaceType(IDecl);
1273 selfTy = Context->getPointerType(selfTy);
1274 if (!LangOpts.MicrosoftExt) {
1276 ResultStr +=
"struct ";
1283 ResultStr += Context->getObjCClassType().getAsString(
1284 Context->getPrintingPolicy());
1286 ResultStr +=
" self, ";
1287 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
1288 ResultStr +=
" _cmd";
1291 for (
const auto *PDecl : OMD->
parameters()) {
1293 if (PDecl->getType()->isObjCQualifiedIdType()) {
1300 (void)convertBlockPointerToFunctionPointer(QT);
1306 ResultStr +=
", ...";
1315 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1316 if (i) ResultStr +=
", ";
1317 std::string ParamStr =
1318 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
1319 ResultStr += ParamStr;
1321 if (FT->isVariadic()) {
1322 if (FT->getNumParams())
1333void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1336 assert((IMD || CID) &&
"Unknown implementation type");
1353 std::string ResultStr;
1358 const char *startBuf =
SM->getCharacterData(LocStart);
1359 const char *endBuf =
SM->getCharacterData(LocEnd);
1360 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1366 std::string ResultStr;
1371 const char *startBuf =
SM->getCharacterData(LocStart);
1372 const char *endBuf =
SM->getCharacterData(LocEnd);
1373 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1376 RewritePropertyImplDecl(I, IMD, CID);
1383 if (ObjCSynthesizedStructs.count(ClassDecl))
1387 while (SuperClass) {
1388 RewriteInterfaceDecl(SuperClass);
1391 std::string ResultStr;
1394 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1395 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1397 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1404 RewriteMethodDeclaration(I);
1406 RewriteMethodDeclaration(I);
1428 DisableReplaceStmtScope S(*
this);
1434 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1435 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1439 for (
unsigned i = 0; i < numArgs; i++) {
1441 if (isa<OpaqueValueExpr>(Arg))
1442 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1443 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1444 Args.push_back(Arg);
1454 case ObjCMessageExpr::Class:
1455 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1467 case ObjCMessageExpr::Instance:
1468 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1480 case ObjCMessageExpr::SuperClass:
1481 case ObjCMessageExpr::SuperInstance:
1482 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1497 Stmt *Replacement = SynthMessageExpr(NewMsg);
1498 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1515 DisableReplaceStmtScope S(*
this);
1519 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1520 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1523 for (
unsigned i = 0; i < numArgs; i++) {
1525 if (isa<OpaqueValueExpr>(Arg))
1526 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1527 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1528 Args.push_back(Arg);
1537 case ObjCMessageExpr::Class:
1538 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1550 case ObjCMessageExpr::Instance:
1551 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1563 case ObjCMessageExpr::SuperClass:
1564 case ObjCMessageExpr::SuperInstance:
1565 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1580 Stmt *Replacement = SynthMessageExpr(NewMsg);
1581 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1594void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1595 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1596 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1598 buf +=
"((id)l_collection,\n\t\t";
1599 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1601 buf +=
"&enumState, "
1602 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1609 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1615 buf =
"goto __break_label_";
1616 buf += utostr(ObjCBcLabelNo.back());
1617 ReplaceText(startLoc, strlen(
"break"), buf);
1622void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1624 std::string &LineString) {
1625 if (
Loc.isFileID() && GenerateLineInfo) {
1626 LineString +=
"\n#line ";
1628 LineString += utostr(PLoc.
getLine());
1629 LineString +=
" \"";
1630 LineString += Lexer::Stringify(PLoc.
getFilename());
1631 LineString +=
"\"\n";
1639 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1645 buf =
"goto __continue_label_";
1646 buf += utostr(ObjCBcLabelNo.back());
1647 ReplaceText(startLoc, strlen(
"continue"), buf);
1686 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1687 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1688 "ObjCForCollectionStmt Statement stack mismatch");
1689 assert(!ObjCBcLabelNo.empty() &&
1690 "ObjCForCollectionStmt - Label No stack empty");
1693 const char *startBuf =
SM->getCharacterData(startLoc);
1694 StringRef elementName;
1695 std::string elementTypeAsString;
1699 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1701 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1703 NamedDecl*
D = cast<NamedDecl>(DS->getSingleDecl());
1704 QualType ElementType = cast<ValueDecl>(
D)->getType();
1708 elementTypeAsString =
"id";
1710 elementTypeAsString = ElementType.
getAsString(Context->getPrintingPolicy());
1711 buf += elementTypeAsString;
1713 elementName =
D->getName();
1718 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1724 elementTypeAsString =
"id";
1730 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1732 buf +=
"id __rw_items[16];\n\t";
1734 buf +=
"id l_collection = (id)";
1736 const char *startCollectionBuf = startBuf;
1737 startCollectionBuf += 3;
1738 startCollectionBuf = strchr(startCollectionBuf,
'(');
1739 startCollectionBuf++;
1741 while (*startCollectionBuf !=
' ' ||
1742 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1743 (*(startCollectionBuf+3) !=
' ' &&
1744 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1745 startCollectionBuf++;
1746 startCollectionBuf += 3;
1749 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1752 const char *rparenBuf =
SM->getCharacterData(rightParenLoc);
1767 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1768 SynthCountByEnumWithState(buf);
1778 buf +=
"if (limit) {\n\t";
1779 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1780 buf +=
"do {\n\t\t";
1781 buf +=
"unsigned long counter = 0;\n\t\t";
1782 buf +=
"do {\n\t\t\t";
1783 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1784 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1787 buf += elementTypeAsString;
1788 buf +=
")enumState.itemsPtr[counter++];";
1790 ReplaceText(lparenLoc, 1, buf);
1804 buf +=
"__continue_label_";
1805 buf += utostr(ObjCBcLabelNo.back());
1808 buf +=
"} while (counter < limit);\n\t";
1809 buf +=
"} while ((limit = ";
1810 SynthCountByEnumWithState(buf);
1814 buf += elementTypeAsString;
1816 buf +=
"__break_label_";
1817 buf += utostr(ObjCBcLabelNo.back());
1820 buf +=
"else\n\t\t";
1823 buf += elementTypeAsString;
1829 if (isa<CompoundStmt>(S->getBody())) {
1831 InsertText(endBodyLoc, buf);
1840 const char *stmtBuf =
SM->getCharacterData(OrigEnd);
1841 const char *semiBuf = strchr(stmtBuf,
';');
1842 assert(semiBuf &&
"Can't find ';'");
1844 InsertText(endBodyLoc, buf);
1847 ObjCBcLabelNo.pop_back();
1851static void Write_RethrowObject(std::string &buf) {
1852 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1853 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1854 buf +=
"\tid rethrow;\n";
1855 buf +=
"\t} _fin_force_rethow(_rethrow);";
1867 const char *startBuf =
SM->getCharacterData(startLoc);
1869 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1873 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1874 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1876 const char *lparenBuf = startBuf;
1877 while (*lparenBuf !=
'(') lparenBuf++;
1878 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1880 buf =
"; objc_sync_enter(_sync_obj);\n";
1881 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1882 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1883 buf +=
"\n\tid sync_exit;";
1884 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1890 const char *RParenExprLocBuf =
SM->getCharacterData(RParenExprLoc);
1891 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1895 const char *LBraceLocBuf =
SM->getCharacterData(LBranceLoc);
1896 assert (*LBraceLocBuf ==
'{');
1897 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->getCharacterData(RParenExprLoc) + 1), buf);
1900 assert((*
SM->getCharacterData(startRBraceLoc) ==
'}') &&
1901 "bogus @synchronized block");
1903 buf =
"} catch (id e) {_rethrow = e;}\n";
1904 Write_RethrowObject(buf);
1908 ReplaceText(startRBraceLoc, 1, buf);
1913void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1916 for (
Stmt *SubStmt : S->children())
1918 WarnAboutReturnGotoStmts(SubStmt);
1920 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1921 Diags.
Report(Context->getFullLoc(S->getBeginLoc()),
1922 TryFinallyContainsReturnDiag);
1928 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1929 ReplaceText(S->getSubStmt()->getBeginLoc(), 1,
1930 "{ __AtAutoreleasePool __autoreleasepool; ");
1937 bool noCatch = S->getNumCatchStmts() == 0;
1940 ConvertSourceLocationToLineDirective(TryLocation, buf);
1944 buf +=
"{ id volatile _rethrow = 0;\n";
1946 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1951 const char *startBuf =
SM->getCharacterData(startLoc);
1953 assert((*startBuf ==
'@') &&
"bogus @try location");
1955 ReplaceText(startLoc, 1, buf);
1958 ReplaceText(startLoc, 1,
"");
1961 VarDecl *catchDecl = Catch->getCatchParamDecl();
1963 startLoc = Catch->getBeginLoc();
1964 bool AtRemoved =
false;
1973 ConvertSourceLocationToLineDirective(Catch->getBeginLoc(), Result);
1975 startBuf =
SM->getCharacterData(startLoc);
1976 assert((*startBuf ==
'@') &&
"bogus @catch location");
1978 const char *rParenBuf =
SM->getCharacterData(rParenLoc);
1984 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1995 ReplaceText(lBraceLoc, 1, Result);
2002 ReplaceText(startLoc, 1,
"");
2010 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2011 buf +=
"catch (id e) {_rethrow = e;}\n";
2015 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2016 buf +=
"catch (id e) {_rethrow = e;}\n";
2020 ReplaceText(startFinalLoc, 8, buf);
2024 Write_RethrowObject(buf);
2025 ReplaceText(startFinalBodyLoc, 1, buf);
2028 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2030 WarnAboutReturnGotoStmts(S->getTryBody());
2042 const char *startBuf =
SM->getCharacterData(startLoc);
2044 assert((*startBuf ==
'@') &&
"bogus @throw location");
2048 if (S->getThrowExpr())
2049 buf =
"objc_exception_throw(";
2054 const char *wBuf = strchr(startBuf,
'w');
2055 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2056 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2059 const char *endBuf =
SM->getCharacterData(endLoc);
2060 const char *semiBuf = strchr(endBuf,
';');
2061 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2063 if (S->getThrowExpr())
2064 ReplaceText(semiLoc, 1,
");");
2070 std::string StrEncoding;
2071 Context->getObjCEncodingForType(Exp->
getEncodedType(), StrEncoding);
2072 Expr *Replacement = getStringLiteral(StrEncoding);
2073 ReplaceStmt(Exp, Replacement);
2081 if (!SelGetUidFunctionDecl)
2082 SynthSelGetUidFunctionDecl();
2083 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2087 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2089 ReplaceStmt(Exp, SelExp);
2095RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2107 QualType pToFunc = Context->getPointerType(msgSendType);
2109 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
2114 CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
2119static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2120 const char *&startRef,
const char *&endRef) {
2121 while (startBuf < endBuf) {
2122 if (*startBuf ==
'<')
2123 startRef = startBuf;
2124 if (*startBuf ==
'>') {
2125 if (startRef && *startRef ==
'<') {
2136static void scanToNextArgument(
const char *&argRef) {
2138 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2141 else if (*argRef ==
'>')
2145 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2148bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2160 QualType ElemTy = Context->getBaseElementType(T);
2161 return needToScanForQualifiers(ElemTy);
2166void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *
E) {
2168 if (needToScanForQualifiers(
Type)) {
2172 Loc = ECE->getLParenLoc();
2173 EndLoc = ECE->getRParenLoc();
2175 Loc =
E->getBeginLoc();
2176 EndLoc =
E->getEndLoc();
2182 const char *startBuf =
SM->getCharacterData(
Loc);
2183 const char *endBuf =
SM->getCharacterData(EndLoc);
2184 const char *startRef =
nullptr, *endRef =
nullptr;
2185 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2190 InsertText(LessLoc,
"/*");
2191 InsertText(GreaterLoc,
"*/");
2196void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2200 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2204 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2209 assert(funcType &&
"missing function type");
2210 proto = dyn_cast<FunctionProtoType>(funcType);
2215 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2220 Loc = TD->getLocation();
2221 Type = TD->getUnderlyingType();
2226 if (needToScanForQualifiers(
Type)) {
2229 const char *endBuf =
SM->getCharacterData(
Loc);
2230 const char *startBuf = endBuf;
2231 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2233 const char *startRef =
nullptr, *endRef =
nullptr;
2234 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2239 InsertText(LessLoc,
"/*");
2240 InsertText(GreaterLoc,
"*/");
2246 const char *startBuf =
SM->getCharacterData(
Loc);
2247 const char *startFuncBuf = startBuf;
2252 const char *endBuf = startBuf;
2254 scanToNextArgument(endBuf);
2255 const char *startRef =
nullptr, *endRef =
nullptr;
2256 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2259 Loc.getLocWithOffset(startRef-startFuncBuf);
2261 Loc.getLocWithOffset(endRef-startFuncBuf+1);
2263 InsertText(LessLoc,
"/*");
2264 InsertText(GreaterLoc,
"*/");
2266 startBuf = ++endBuf;
2271 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2278void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2281 if (!isa<TypeOfExprType>(TypePtr))
2283 while (isa<TypeOfExprType>(TypePtr)) {
2284 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2290 std::string TypeAsString(QT.
getAsString(Context->getPrintingPolicy()));
2292 const char *startBuf =
SM->getCharacterData(DeclLoc);
2295 TypeAsString +=
" " + Name +
" = ";
2299 startLoc = ECE->getLParenLoc();
2301 startLoc =
E->getBeginLoc();
2302 startLoc =
SM->getExpansionLoc(startLoc);
2303 const char *endBuf =
SM->getCharacterData(startLoc);
2304 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2308 X =
SM->getExpansionLoc(
X);
2309 const char *endBuf =
SM->getCharacterData(
X);
2310 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2315void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2316 IdentifierInfo *SelGetUidIdent = &Context->Idents.get(
"sel_registerName");
2318 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2320 getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
2321 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2324 SelGetUidIdent, getFuncType,
2325 nullptr, SC_Extern);
2328void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2331 FD->
getName() ==
"sel_registerName") {
2332 SelGetUidFunctionDecl = FD;
2335 RewriteObjCQualifiedInterfaceTypes(FD);
2338void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2339 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2340 const char *argPtr = TypeString.c_str();
2341 if (!strchr(argPtr,
'^')) {
2346 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2352void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2355 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2356 const char *argPtr = TypeString.c_str();
2381void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2388 std::string FdStr =
Type.getAsString(Context->getPrintingPolicy());
2392 unsigned numArgs = proto->getNumParams();
2393 for (
unsigned i = 0; i < numArgs; i++) {
2394 QualType ArgType = proto->getParamType(i);
2395 RewriteBlockPointerType(FdStr, ArgType);
2400 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2404 InsertText(FunLocStart, FdStr);
2408void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2409 if (SuperConstructorFunctionDecl)
2411 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"__rw_objc_super");
2413 QualType argT = Context->getObjCIdType();
2414 assert(!argT.
isNull() &&
"Can't find 'id' type");
2415 ArgTys.push_back(argT);
2416 ArgTys.push_back(argT);
2417 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2419 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2422 msgSendIdent, msgSendType,
2423 nullptr, SC_Extern);
2427void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2428 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend");
2430 QualType argT = Context->getObjCIdType();
2431 assert(!argT.
isNull() &&
"Can't find 'id' type");
2432 ArgTys.push_back(argT);
2433 argT = Context->getObjCSelType();
2434 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2435 ArgTys.push_back(argT);
2436 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2438 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2441 msgSendIdent, msgSendType,
nullptr,
2446void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2447 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSendSuper");
2449 ArgTys.push_back(Context->VoidTy);
2450 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2452 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2455 msgSendIdent, msgSendType,
2456 nullptr, SC_Extern);
2460void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2461 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_stret");
2463 QualType argT = Context->getObjCIdType();
2464 assert(!argT.
isNull() &&
"Can't find 'id' type");
2465 ArgTys.push_back(argT);
2466 argT = Context->getObjCSelType();
2467 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2468 ArgTys.push_back(argT);
2469 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2471 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2474 msgSendIdent, msgSendType,
2475 nullptr, SC_Extern);
2480void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2482 &Context->Idents.get(
"objc_msgSendSuper_stret");
2484 ArgTys.push_back(Context->VoidTy);
2485 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2487 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2491 msgSendType,
nullptr,
2496void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2497 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_fpret");
2499 QualType argT = Context->getObjCIdType();
2500 assert(!argT.
isNull() &&
"Can't find 'id' type");
2501 ArgTys.push_back(argT);
2502 argT = Context->getObjCSelType();
2503 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2504 ArgTys.push_back(argT);
2505 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
2507 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2510 msgSendIdent, msgSendType,
2511 nullptr, SC_Extern);
2515void RewriteModernObjC::SynthGetClassFunctionDecl() {
2516 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getClass");
2518 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2519 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2521 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2524 getClassIdent, getClassType,
2525 nullptr, SC_Extern);
2529void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2531 &Context->Idents.get(
"class_getSuperclass");
2533 ArgTys.push_back(Context->getObjCClassType());
2534 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2536 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2540 getClassType,
nullptr,
2545void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2546 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getMetaClass");
2548 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2549 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2551 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2554 getClassIdent, getClassType,
2555 nullptr, SC_Extern);
2559 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2560 QualType strType = getConstantStringStructType();
2562 std::string S =
"__NSConstantStringImpl_";
2564 std::string tmpName = InFileName;
2566 for (i=0; i < tmpName.length(); i++) {
2567 char c = tmpName.at(i);
2574 S += utostr(NumObjCStringLiterals++);
2576 Preamble +=
"static __NSConstantStringImpl " + S;
2577 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2580 std::string prettyBufS;
2581 llvm::raw_string_ostream prettyBuf(prettyBufS);
2589 strType,
nullptr, SC_Static);
2592 Expr *Unop = UnaryOperator::Create(
2593 const_cast<ASTContext &
>(*Context), DRE, UO_AddrOf,
2594 Context->getPointerType(DRE->
getType()), VK_PRValue, OK_Ordinary,
2598 CK_CPointerToObjCPointerCast, Unop);
2599 ReplaceStmt(Exp, cast);
2606 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
2608 Expr *FlagExp = IntegerLiteral::Create(*Context,
2609 llvm::APInt(IntSize, Exp->
getValue()),
2611 CastExpr *
cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
2612 CK_BitCast, FlagExp);
2615 ReplaceStmt(Exp, PE);
2621 if (!SelGetUidFunctionDecl)
2622 SynthSelGetUidFunctionDecl();
2624 if (!MsgSendFunctionDecl)
2625 SynthMsgSendFunctionDecl();
2626 if (!GetClassFunctionDecl)
2627 SynthGetClassFunctionDecl();
2642 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2643 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2645 MsgExprs.push_back(Cls);
2652 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2653 SelExprs, StartLoc, EndLoc);
2654 MsgExprs.push_back(SelExp);
2663 CK = CK_IntegralToBoolean;
2664 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2666 MsgExprs.push_back(subExpr);
2669 ArgTypes.push_back(Context->getObjCClassType());
2670 ArgTypes.push_back(Context->getObjCSelType());
2671 for (
const auto PI : BoxingMethod->
parameters())
2672 ArgTypes.push_back(PI->getType());
2680 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2683 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2687 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2688 castType = Context->getPointerType(castType);
2689 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2696 CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
2698 ReplaceStmt(Exp, CE);
2704 if (!SelGetUidFunctionDecl)
2705 SynthSelGetUidFunctionDecl();
2707 if (!MsgSendFunctionDecl)
2708 SynthMsgSendFunctionDecl();
2709 if (!GetClassFunctionDecl)
2710 SynthGetClassFunctionDecl();
2719 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2720 std::string NSArrayFName(
"__NSContainer_literal");
2721 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2723 *Context, NSArrayFD,
false, NSArrayFType, VK_PRValue,
SourceLocation());
2727 unsigned UnsignedIntSize =
2728 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2729 Expr *count = IntegerLiteral::Create(*Context,
2730 llvm::APInt(UnsignedIntSize, NumElements),
2732 InitExprs.push_back(count);
2733 for (
unsigned i = 0; i < NumElements; i++)
2735 Expr *NSArrayCallExpr =
2736 CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue,
2741 &Context->Idents.get(
"arr"),
2742 Context->getPointerType(Context->VoidPtrTy),
2746 MemberExpr::CreateImplicit(*Context, NSArrayCallExpr,
false, ARRFD,
2747 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2748 QualType ConstIdT = Context->getObjCIdType().withConst();
2750 NoTypeInfoCStyleCastExpr(Context,
2751 Context->getPointerType(ConstIdT),
2765 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2766 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2768 MsgExprs.push_back(Cls);
2776 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2777 SelExprs, StartLoc, EndLoc);
2778 MsgExprs.push_back(SelExp);
2781 MsgExprs.push_back(ArrayLiteralObjects);
2784 Expr *cnt = IntegerLiteral::Create(*Context,
2785 llvm::APInt(UnsignedIntSize, NumElements),
2787 MsgExprs.push_back(cnt);
2790 ArgTypes.push_back(Context->getObjCClassType());
2791 ArgTypes.push_back(Context->getObjCSelType());
2792 for (
const auto *PI : ArrayMethod->
parameters())
2793 ArgTypes.push_back(PI->getType());
2801 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2804 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2808 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2809 castType = Context->getPointerType(castType);
2810 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2819 ReplaceStmt(Exp, CE);
2825 if (!SelGetUidFunctionDecl)
2826 SynthSelGetUidFunctionDecl();
2828 if (!MsgSendFunctionDecl)
2829 SynthMsgSendFunctionDecl();
2830 if (!GetClassFunctionDecl)
2831 SynthGetClassFunctionDecl();
2840 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2841 std::string NSDictFName(
"__NSContainer_literal");
2842 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2844 *Context, NSDictFD,
false, NSDictFType, VK_PRValue,
SourceLocation());
2850 unsigned UnsignedIntSize =
2851 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2852 Expr *count = IntegerLiteral::Create(*Context,
2853 llvm::APInt(UnsignedIntSize, NumElements),
2855 KeyExprs.push_back(count);
2856 ValueExprs.push_back(count);
2857 for (
unsigned i = 0; i < NumElements; i++) {
2859 KeyExprs.push_back(Element.Key);
2860 ValueExprs.push_back(Element.Value);
2864 Expr *NSValueCallExpr =
2865 CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue,
2870 &Context->Idents.get(
"arr"),
2871 Context->getPointerType(Context->VoidPtrTy),
2875 MemberExpr::CreateImplicit(*Context, NSValueCallExpr,
false, ARRFD,
2876 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2877 QualType ConstIdT = Context->getObjCIdType().withConst();
2879 NoTypeInfoCStyleCastExpr(Context,
2880 Context->getPointerType(ConstIdT),
2882 DictLiteralValueME);
2884 Expr *NSKeyCallExpr =
2885 CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue,
2889 MemberExpr::CreateImplicit(*Context, NSKeyCallExpr,
false, ARRFD,
2890 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2893 NoTypeInfoCStyleCastExpr(Context,
2894 Context->getPointerType(ConstIdT),
2908 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2909 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2911 MsgExprs.push_back(Cls);
2918 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2919 SelExprs, StartLoc, EndLoc);
2920 MsgExprs.push_back(SelExp);
2923 MsgExprs.push_back(DictValueObjects);
2926 MsgExprs.push_back(DictKeyObjects);
2929 Expr *cnt = IntegerLiteral::Create(*Context,
2930 llvm::APInt(UnsignedIntSize, NumElements),
2932 MsgExprs.push_back(cnt);
2935 ArgTypes.push_back(Context->getObjCClassType());
2936 ArgTypes.push_back(Context->getObjCSelType());
2937 for (
const auto *PI : DictMethod->
parameters()) {
2941 convertToUnqualifiedObjCType(PointeeTy);
2942 T = Context->getPointerType(PointeeTy);
2944 ArgTypes.push_back(T);
2953 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2956 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2960 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2961 castType = Context->getPointerType(castType);
2962 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2971 ReplaceStmt(Exp, CE);
2978QualType RewriteModernObjC::getSuperStructType() {
2979 if (!SuperStructDecl) {
2980 SuperStructDecl = RecordDecl::Create(
2986 FieldTypes[0] = Context->getObjCIdType();
2988 FieldTypes[1] = Context->getObjCIdType();
2991 for (
unsigned i = 0; i < 2; ++i) {
2992 SuperStructDecl->
addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2995 FieldTypes[i],
nullptr,
3003 return Context->getTagDeclType(SuperStructDecl);
3006QualType RewriteModernObjC::getConstantStringStructType() {
3007 if (!ConstantStringDecl) {
3008 ConstantStringDecl = RecordDecl::Create(
3010 SourceLocation(), &Context->Idents.get(
"__NSConstantStringImpl"));
3014 FieldTypes[0] = Context->getObjCIdType();
3016 FieldTypes[1] = Context->IntTy;
3018 FieldTypes[2] = Context->getPointerType(Context->CharTy);
3020 FieldTypes[3] = Context->LongTy;
3023 for (
unsigned i = 0; i < 4; ++i) {
3024 ConstantStringDecl->
addDecl(FieldDecl::Create(*Context,
3028 FieldTypes[i],
nullptr,
3036 return Context->getTagDeclType(ConstantStringDecl);
3042static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3048 if (!LSD->getRBraceLoc().isValid())
3049 return LSD->getExternLoc();
3052 R.RewriteBlockLiteralFunctionDecl(FD);
3056void RewriteModernObjC::RewriteLineDirective(
const Decl *
D) {
3060 if (Location.
isFileID() && GenerateLineInfo) {
3061 std::string LineString(
"\n#line ");
3063 LineString += utostr(PLoc.
getLine());
3064 LineString +=
" \"";
3065 LineString += Lexer::Stringify(PLoc.
getFilename());
3066 if (isa<ObjCMethodDecl>(
D))
3068 else LineString +=
"\"\n";
3070 Location =
D->getBeginLoc();
3076 if (!LSD->getRBraceLoc().isValid())
3077 Location = LSD->getExternLoc();
3080 InsertText(Location, LineString);
3094Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3100 QualType FuncType = getSimpleFunctionType(
3101 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3102 QualType castType = Context->getPointerType(FuncType);
3105 static unsigned stretCount=0;
3106 std::string
name =
"__Stret";
name += utostr(stretCount);
3108 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3109 str +=
"namespace {\n";
3110 str +=
"struct "; str +=
name;
3113 str +=
"(id receiver, SEL sel";
3114 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3115 std::string ArgName =
"arg"; ArgName += utostr(i);
3116 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
3117 str +=
", "; str += ArgName;
3120 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3121 std::string ArgName =
"arg"; ArgName += utostr(i);
3122 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3123 Context->getPrintingPolicy());
3124 str +=
", "; str += ArgName;
3128 str +=
"\t unsigned size = sizeof(";
3129 str += returnType.
getAsString(Context->getPrintingPolicy()); str +=
");\n";
3131 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3133 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3134 str +=
")(void *)objc_msgSend)(receiver, sel";
3135 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3136 str +=
", arg"; str += utostr(i);
3139 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3140 str +=
", arg"; str += utostr(i);
3144 str +=
"\t else if (receiver == 0)\n";
3145 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3148 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3149 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3150 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3151 str +=
", arg"; str += utostr(i);
3154 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3155 str +=
", arg"; str += utostr(i);
3160 str +=
"\t"; str += returnType.
getAsString(Context->getPrintingPolicy());
3162 str +=
"};\n};\n\n";
3165 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3167 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3171 InsertText(FunLocStart, str);
3178 ID, FuncType,
nullptr, SC_Extern,
false,
false);
3182 CallExpr::Create(*Context, DRE, MsgExprs, castType, VK_LValue,
3187 &Context->Idents.get(
"s"),
3188 returnType,
nullptr,
3192 *Context, STCE,
false, FieldD, FieldD->
getType(), VK_LValue, OK_Ordinary);
3200 if (!SelGetUidFunctionDecl)
3201 SynthSelGetUidFunctionDecl();
3202 if (!MsgSendFunctionDecl)
3203 SynthMsgSendFunctionDecl();
3204 if (!MsgSendSuperFunctionDecl)
3205 SynthMsgSendSuperFunctionDecl();
3206 if (!MsgSendStretFunctionDecl)
3207 SynthMsgSendStretFunctionDecl();
3208 if (!MsgSendSuperStretFunctionDecl)
3209 SynthMsgSendSuperStretFunctionDecl();
3210 if (!MsgSendFpretFunctionDecl)
3211 SynthMsgSendFpretFunctionDecl();
3212 if (!GetClassFunctionDecl)
3213 SynthGetClassFunctionDecl();
3214 if (!GetSuperClassFunctionDecl)
3215 SynthGetSuperClassFunctionDecl();
3216 if (!GetMetaClassFunctionDecl)
3217 SynthGetMetaClassFunctionDecl();
3224 QualType resultType = mDecl->getReturnType();
3226 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3228 MsgSendFlavor = MsgSendFpretFunctionDecl;
3234 case ObjCMessageExpr::SuperClass: {
3235 MsgSendFlavor = MsgSendSuperFunctionDecl;
3236 if (MsgSendStretFlavor)
3237 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3238 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3245 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3246 Context, Context->getObjCIdType(), CK_BitCast,
3248 Context->getObjCIdType(), VK_PRValue,
3255 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3256 ClsExprs, StartLoc, EndLoc);
3258 ClsExprs.push_back(Cls);
3259 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3264 InitExprs.push_back(
3265 NoTypeInfoCStyleCastExpr(Context,
3266 Context->getObjCIdType(),
3269 QualType superType = getSuperStructType();
3272 if (LangOpts.MicrosoftExt) {
3273 SynthSuperConstructorFunctionDecl();
3276 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3279 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3287 SuperRep = UnaryOperator::Create(
3288 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3289 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3291 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3292 Context->getPointerType(superType),
3293 CK_BitCast, SuperRep);
3300 = Context->getTrivialTypeSourceInfo(superType);
3305 SuperRep = UnaryOperator::Create(
3306 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3307 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3310 MsgExprs.push_back(SuperRep);
3314 case ObjCMessageExpr::Class: {
3319 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3320 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3322 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3323 Context->getObjCIdType(),
3325 MsgExprs.push_back(ArgExpr);
3329 case ObjCMessageExpr::SuperInstance:{
3330 MsgSendFlavor = MsgSendSuperFunctionDecl;
3331 if (MsgSendStretFlavor)
3332 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3333 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3337 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3338 Context, Context->getObjCIdType(), CK_BitCast,
3340 Context->getObjCIdType(), VK_PRValue,
3347 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3350 ClsExprs.push_back(Cls);
3351 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3356 InitExprs.push_back(
3358 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3361 QualType superType = getSuperStructType();
3364 if (LangOpts.MicrosoftExt) {
3365 SynthSuperConstructorFunctionDecl();
3368 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3371 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3379 SuperRep = UnaryOperator::Create(
3380 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3381 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3383 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3384 Context->getPointerType(superType),
3385 CK_BitCast, SuperRep);
3392 = Context->getTrivialTypeSourceInfo(superType);
3396 MsgExprs.push_back(SuperRep);
3400 case ObjCMessageExpr::Instance: {
3405 recExpr = CE->getSubExpr();
3408 ? CK_BlockPointerToObjCPointerCast
3409 : CK_CPointerToObjCPointerCast;
3411 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3413 MsgExprs.push_back(recExpr);
3421 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3422 SelExprs, StartLoc, EndLoc);
3423 MsgExprs.push_back(SelExp);
3426 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3432 if (needToScanForQualifiers(type))
3433 type = Context->getObjCIdType();
3435 (void)convertBlockPointerToFunctionPointer(type);
3439 type->isBooleanType()) {
3440 CK = CK_IntegralToBoolean;
3441 }
else if (
type->isObjCObjectPointerType()) {
3443 CK = CK_BlockPointerToObjCPointerCast;
3445 CK = CK_CPointerToObjCPointerCast;
3453 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3456 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3457 if (CE->getType()->isObjCQualifiedIdType()) {
3458 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3459 userExpr = CE->getSubExpr();
3462 CK = CK_IntegralToPointer;
3464 CK = CK_BlockPointerToObjCPointerCast;
3466 CK = CK_CPointerToObjCPointerCast;
3470 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3474 MsgExprs.push_back(userExpr);
3486 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3487 ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
3489 ArgTypes.push_back(Context->getObjCIdType());
3490 ArgTypes.push_back(Context->getObjCSelType());
3495 ? Context->getObjCIdType()
3498 (void)convertBlockPointerToFunctionPointer(t);
3499 ArgTypes.push_back(t);
3502 convertToUnqualifiedObjCType(returnType);
3503 (void)convertBlockPointerToFunctionPointer(returnType);
3505 returnType = Context->getObjCIdType();
3512 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
3518 cast = NoTypeInfoCStyleCastExpr(Context,
3519 Context->getPointerType(Context->VoidTy),
3526 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->
isVariadic() :
true);
3527 castType = Context->getPointerType(castType);
3528 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3537 Stmt *ReplacingStmt = CE;
3538 if (MsgSendStretFlavor) {
3544 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3548 ReplacingStmt = STCE;
3551 return ReplacingStmt;
3555 Stmt *ReplacingStmt =
3559 ReplaceStmt(Exp, ReplacingStmt);
3562 return ReplacingStmt;
3566QualType RewriteModernObjC::getProtocolType() {
3567 if (!ProtocolTypeDecl) {
3569 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3570 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3572 &Context->Idents.get(
"Protocol"),
3575 return Context->getTypeDeclType(ProtocolTypeDecl);
3583 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3588 nullptr, SC_Extern);
3592 Context, Context->getPointerType(DRE->
getType()), CK_BitCast, DRE);
3593 ReplaceStmt(Exp, castExpr);
3603 bool &IsNamedDefinition) {
3607 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3611 IsNamedDefinition =
true;
3613 return Context->getSourceManager().isBeforeInTranslationUnit(
3616 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3617 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3619 IsNamedDefinition =
true;
3620 TagLocation = ED->getLocation();
3621 return Context->getSourceManager().isBeforeInTranslationUnit(
3629bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &
Type,
3630 std::string &Result) {
3638 return RewriteObjCFieldDeclType(ElemTy, Result);
3644 Result +=
"\n\tstruct ";
3646 Result +=
"\n\tunion ";
3648 assert(
false &&
"class not allowed as an ivar type");
3651 if (GlobalDefinedTags.count(RD)) {
3657 for (
auto *FD : RD->
fields())
3658 RewriteObjCFieldDecl(FD, Result);
3666 Result +=
"\n\tenum ";
3668 if (GlobalDefinedTags.count(ED)) {
3676 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3677 Result +=
toString(EC->getInitVal(), 10);
3686 convertObjCTypeToCStyleType(
Type);
3693void RewriteModernObjC::RewriteObjCFieldDecl(
FieldDecl *fieldDecl,
3694 std::string &Result) {
3696 std::string Name =
fieldDecl->getNameAsString();
3698 bool EleboratedType = RewriteObjCFieldDeclType(
Type, Result);
3699 if (!EleboratedType)
3700 Type.getAsStringInternal(Name, Context->getPrintingPolicy());
3703 Result +=
" : "; Result += utostr(
fieldDecl->getBitWidthValue(*Context));
3710 llvm::APInt Dim = CAT->getSize();
3711 Result += utostr(Dim.getZExtValue());
3723void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3724 std::string &Result) {
3729 Type = Context->getBaseElementType(
Type);
3731 auto *IDecl = dyn_cast<ObjCContainerDecl>(
fieldDecl->getDeclContext());
3742 if (GlobalDefinedTags.count(TD))
3745 bool IsNamedDefinition =
false;
3746 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3747 RewriteObjCFieldDeclType(
Type, Result);
3750 if (IsNamedDefinition)
3751 GlobalDefinedTags.insert(TD);
3755unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3757 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3758 return IvarGroupNumber[IV];
3760 unsigned GroupNo = 0;
3764 IVars.push_back(IVD);
3766 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3767 if (IVars[i]->isBitField()) {
3768 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3769 while (i < e && IVars[i]->isBitField())
3770 IvarGroupNumber[IVars[i++]] = GroupNo;
3775 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3776 return IvarGroupNumber[IV];
3779QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3782 std::string StructTagName;
3783 ObjCIvarBitfieldGroupType(IV, StructTagName);
3785 *Context, TagTypeKind::Struct, Context->getTranslationUnitDecl(),
3787 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3790 &Context->Idents.get(Ivar->
getName()),
3793 false, ICIS_NoInit));
3796 return Context->getTagDeclType(RD);
3801 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3802 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3803 if (GroupRecordType.count(tuple))
3804 return GroupRecordType[tuple];
3809 if (IVD->isBitField())
3812 if (!IVars.empty()) {
3813 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3815 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3816 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3821 if (!IVars.empty()) {
3823 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3824 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3825 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3827 QualType RetQT = GroupRecordType[tuple];
3828 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3835void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3836 std::string &Result) {
3839 Result +=
"__GRBF_";
3840 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3841 Result += utostr(GroupNo);
3847void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3848 std::string &Result) {
3852 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3853 Result += utostr(GroupNo);
3859void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3860 std::string &Result) {
3861 Result +=
"OBJC_IVAR_$_";
3862 ObjCIvarBitfieldGroupDecl(IV, Result);
3865#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3866 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3875 std::string &Result) {
3876 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3877 assert(CDecl->
getName() !=
"" &&
3878 "Name missing in SynthesizeObjCInternalStruct");
3883 IVars.push_back(IVD);
3888 const char *startBuf =
SM->getCharacterData(LocStart);
3889 const char *endBuf =
SM->getCharacterData(LocEnd);
3894 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3895 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3896 ReplaceText(LocStart, endBuf-startBuf, Result);
3903 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3904 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3908 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3909 if (IVars[i]->isBitField()) {
3911 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3912 RewriteObjCFieldDeclType(QT, Result);
3915 SKIP_BITFIELDS(i , e, IVars);
3918 Result +=
"\nstruct ";
3920 Result +=
"_IMPL {\n";
3922 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3925 Result +=
"_IVARS;\n";
3928 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3929 if (IVars[i]->isBitField()) {
3931 Result +=
"\tstruct ";
3932 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3933 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3935 SKIP_BITFIELDS(i , e, IVars);
3938 RewriteObjCFieldDecl(IVars[i], Result);
3942 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3943 ReplaceText(LocStart, endBuf-startBuf, Result);
3945 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3946 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3952 std::string &Result) {
3963 unsigned GroupNo = 0;
3965 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3966 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3970 if (LangOpts.MicrosoftExt)
3971 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3972 Result +=
"extern \"C\" ";
3973 if (LangOpts.MicrosoftExt &&
3976 Result +=
"__declspec(dllimport) ";
3978 Result +=
"unsigned long ";
3980 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3981 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3984 WriteInternalIvarName(CDecl, IvarDecl, Result);
3996void RewriteModernObjC::RewriteImplementations() {
3997 int ClsDefCount = ClassImplementation.size();
3998 int CatDefCount = CategoryImplementation.size();
4001 for (
int i = 0; i < ClsDefCount; i++) {
4006 "Legacy implicit interface rewriting not supported in moder abi");
4007 RewriteImplementationDecl(OIMP);
4010 for (
int i = 0; i < CatDefCount; i++) {
4015 "Legacy implicit interface rewriting not supported in moder abi");
4016 RewriteImplementationDecl(CIMP);
4020void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4021 const std::string &Name,
4023 assert(BlockByRefDeclNo.count(VD) &&
4024 "RewriteByRefString: ByRef decl missing");
4026 ResultStr +=
"struct ";
4027 ResultStr +=
"__Block_byref_" + Name +
4028 "_" + utostr(BlockByRefDeclNo[VD]) ;
4031static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4032 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4033 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4037std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4039 const std::string &Tag) {
4042 std::string StructRef =
"struct " +
Tag;
4045 ConvertSourceLocationToLineDirective(BlockLoc, S);
4047 S +=
"static " + RT.
getAsString(Context->getPrintingPolicy()) +
" __" +
4048 funcName.str() +
"_block_func_" + utostr(i);
4052 if (isa<FunctionNoProtoType>(AFT)) {
4055 S +=
"(" + StructRef +
" *__cself)";
4057 S +=
"(" + StructRef +
" *__cself)";
4060 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4063 S += StructRef +
" *__cself, ";
4064 std::string ParamStr;
4068 ParamStr = (*AI)->getNameAsString();
4070 (void)convertBlockPointerToFunctionPointer(QT);
4085 E = BlockByRefDecls.end(); I !=
E; ++I) {
4087 std::string Name = (*I)->getNameAsString();
4088 std::string TypeString;
4089 RewriteByRefString(TypeString, Name, (*I));
4091 Name = TypeString + Name;
4092 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4096 E = BlockByCopyDecls.end(); I !=
E; ++I) {
4108 if (isTopLevelBlockPointerType((*I)->getType())) {
4109 RewriteBlockPointerTypeVariable(S, (*I));
4111 RewriteBlockPointerType(S, (*I)->getType());
4113 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4116 std::string Name = (*I)->getNameAsString();
4118 if (HasLocalVariableExternalStorage(*I))
4119 QT = Context->getPointerType(QT);
4121 S += Name +
" = __cself->" +
4122 (*I)->getNameAsString() +
"; // bound by copy\n";
4125 std::string RewrittenStr = RewrittenBlockExprs[CE];
4126 const char *cstr = RewrittenStr.c_str();
4127 while (*cstr++ !=
'{') ;
4133std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
4134 BlockExpr *CE,
int i, StringRef funcName,
const std::string &Tag) {
4135 std::string StructRef =
"struct " +
Tag;
4136 std::string S =
"static void __";
4139 S +=
"_block_copy_" + utostr(i);
4140 S +=
"(" + StructRef;
4141 S +=
"*dst, " + StructRef;
4143 for (
ValueDecl *VD : ImportedBlockDecls) {
4144 S +=
"_Block_object_assign((void*)&dst->";
4146 S +=
", (void*)src->";
4148 if (BlockByRefDeclsPtrSet.count(VD))
4149 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4151 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4153 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4157 S +=
"\nstatic void __";
4159 S +=
"_block_dispose_" + utostr(i);
4160 S +=
"(" + StructRef;
4162 for (
ValueDecl *VD : ImportedBlockDecls) {
4163 S +=
"_Block_object_dispose((void*)src->";
4165 if (BlockByRefDeclsPtrSet.count(VD))
4166 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4168 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4170 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4176std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE,
4177 const std::string &Tag,
4178 const std::string &Desc) {
4179 std::string S =
"\nstruct " +
Tag;
4182 S +=
" {\n struct __block_impl impl;\n";
4183 S +=
" struct " + Desc;
4190 if (BlockDeclRefs.size()) {
4193 E = BlockByCopyDecls.end(); I !=
E; ++I) {
4195 std::string FieldName = (*I)->getNameAsString();
4196 std::string ArgName =
"_" + FieldName;
4207 if (isTopLevelBlockPointerType((*I)->getType())) {
4208 S +=
"struct __block_impl *";
4212 if (HasLocalVariableExternalStorage(*I))
4213 QT = Context->getPointerType(QT);
4218 S += FieldName +
";\n";
4222 E = BlockByRefDecls.end(); I !=
E; ++I) {
4224 std::string FieldName = (*I)->getNameAsString();
4225 std::string ArgName =
"_" + FieldName;
4227 std::string TypeString;
4228 RewriteByRefString(TypeString, FieldName, (*I));
4230 FieldName = TypeString + FieldName;
4231 ArgName = TypeString + ArgName;
4234 S += FieldName +
"; // by ref\n";
4239 bool firsTime =
true;
4241 E = BlockByCopyDecls.end(); I !=
E; ++I) {
4242 std::string Name = (*I)->getNameAsString();
4249 if (isTopLevelBlockPointerType((*I)->getType()))
4250 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4256 E = BlockByRefDecls.end(); I !=
E; ++I) {
4257 std::string Name = (*I)->getNameAsString();
4264 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4269 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4271 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4272 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4279 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4281 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4282 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4292std::string RewriteModernObjC::SynthesizeBlockDescriptor(
4293 const std::string &DescTag,
const std::string &ImplTag,
int i,
4294 StringRef FunName,
unsigned hasCopy) {
4295 std::string S =
"\nstatic struct " + DescTag;
4297 S +=
" {\n size_t reserved;\n";
4298 S +=
" size_t Block_size;\n";
4300 S +=
" void (*copy)(struct ";
4301 S += ImplTag; S +=
"*, struct ";
4302 S += ImplTag; S +=
"*);\n";
4304 S +=
" void (*dispose)(struct ";
4305 S += ImplTag; S +=
"*);\n";
4309 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4312 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4313 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4319void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4320 StringRef FunName) {
4321 bool RewriteSC = (GlobalVarDecl &&
4326 std::string SC(
" void __");
4329 InsertText(FunLocStart, SC);
4333 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4334 CollectBlockDeclRefInfo(Blocks[i]);
4337 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4340 BlockDeclRefs.push_back(Exp);
4341 if (!VD->
hasAttr<BlocksAttr>()) {
4342 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4343 BlockByCopyDeclsPtrSet.insert(VD);
4344 BlockByCopyDecls.push_back(VD);
4349 if (!BlockByRefDeclsPtrSet.count(VD)) {
4350 BlockByRefDeclsPtrSet.insert(VD);
4351 BlockByRefDecls.push_back(VD);
4358 ImportedBlockDecls.insert(VD);
4361 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4362 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4364 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4366 InsertText(FunLocStart, CI);
4368 std::string
CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4370 InsertText(FunLocStart, CF);
4372 if (ImportedBlockDecls.size()) {
4373 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4374 InsertText(FunLocStart, HF);
4376 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4377 ImportedBlockDecls.size() > 0);
4378 InsertText(FunLocStart, BD);
4380 BlockDeclRefs.clear();
4381 BlockByRefDecls.clear();
4382 BlockByRefDeclsPtrSet.clear();
4383 BlockByCopyDecls.clear();
4384 BlockByCopyDeclsPtrSet.clear();
4385 ImportedBlockDecls.clear();
4399 InsertText(FunLocStart, SC);
4401 if (GlobalConstructionExp) {
4405 std::string
Tag =
"__";
4407 Tag +=
"_block_impl_";
4408 Tag += utostr(Blocks.size()-1);
4409 std::string globalBuf =
"static ";
4410 globalBuf +=
Tag; globalBuf +=
" ";
4413 llvm::raw_string_ostream constructorExprBuf(SStr);
4414 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4418 InsertText(FunLocStart, globalBuf);
4419 GlobalConstructionExp =
nullptr;
4423 InnerDeclRefsCount.clear();
4424 InnerDeclRefs.clear();
4425 RewrittenBlockExprs.clear();
4428void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4430 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4432 StringRef FuncName = FD->
getName();
4434 SynthesizeBlockLiterals(FunLocStart, FuncName);
4437static void BuildUniqueMethodName(std::string &Name,
4440 Name = std::string(IFace->
getName());
4443 std::string::size_type loc = 0;
4444 while ((loc = Name.find(
':', loc)) != std::string::npos)
4445 Name.replace(loc, 1,
"_");
4448void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4452 std::string FuncName;
4453 BuildUniqueMethodName(FuncName, MD);
4454 SynthesizeBlockLiterals(FunLocStart, FuncName);
4457void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4458 for (
Stmt *SubStmt : S->children())
4460 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4461 GetBlockDeclRefExprs(CBE->getBody());
4463 GetBlockDeclRefExprs(SubStmt);
4468 HasLocalVariableExternalStorage(DRE->
getDecl()))
4470 BlockDeclRefs.push_back(DRE);
4473void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4475 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4476 for (
Stmt *SubStmt : S->children())
4478 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4479 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4480 GetInnerBlockDeclRefExprs(CBE->getBody(),
4485 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4488 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4490 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4492 InnerBlockDeclRefs.push_back(DRE);
4494 if (Var->isFunctionOrMethodVarDecl())
4495 ImportedLocalExternalDecls.insert(Var);
4503bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4505 convertBlockPointerToFunctionPointer(T);
4511 T = convertFunctionTypeOfBlocks(FT);
4512 T = Context->getPointerType(T);
4517 convertToUnqualifiedObjCType(T);
4531 bool modified = convertObjCTypeToCStyleType(Res);
4537 if (convertObjCTypeToCStyleType(t))
4539 ArgTypes.push_back(t);
4544 FuncType = getSimpleFunctionType(Res, ArgTypes);
4549Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4553 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4555 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4558 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4559 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4561 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4564 dyn_cast<ConditionalOperator>(BlockExp)) {
4565 Expr *LHSExp = CEXPR->getLHS();
4566 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4567 Expr *RHSExp = CEXPR->getRHS();
4568 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4569 Expr *CONDExp = CEXPR->getCond();
4574 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4577 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4580 assert(
false &&
"RewriteBlockClass: Bad type");
4582 assert(CPT &&
"RewriteBlockClass: Bad type");
4584 assert(FT &&
"RewriteBlockClass: Bad type");
4588 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
4590 &Context->Idents.get(
"__block_impl"));
4591 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4597 ArgTypes.push_back(PtrBlock);
4602 if (!convertBlockPointerToFunctionPointer(t))
4603 convertToUnqualifiedObjCType(t);
4604 ArgTypes.push_back(t);
4608 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4610 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4612 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4614 const_cast<Expr*
>(BlockExp));
4622 &Context->Idents.get(
"FuncPtr"),
4623 Context->VoidPtrTy,
nullptr,
4627 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4629 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4635 BlkExprs.push_back(BlkCast);
4639 BlkExprs.push_back(*I);
4642 CallExpr::Create(*Context, PE, BlkExprs, Exp->
getType(), VK_PRValue,
4660Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4665 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4669 &Context->Idents.get(
"__forwarding"),
4670 Context->VoidPtrTy,
nullptr,
4674 *Context, DeclRefExp, isArrow, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4676 StringRef Name = VD->
getName();
4678 &Context->Idents.get(Name),
4679 Context->VoidPtrTy,
nullptr,
4682 ME = MemberExpr::CreateImplicit(*Context, ME,
true, FD, DeclRefExp->
getType(),
4683 VK_LValue, OK_Ordinary);
4689 ReplaceStmt(DeclRefExp, PE);
4696Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4698 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4699 if (!ImportedLocalExternalDecls.count(Var))
4701 Expr *Exp = UnaryOperator::Create(
4707 ReplaceStmt(DRE, PE);
4719 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4722 const char *startBuf =
SM->getCharacterData(LocStart);
4723 const char *endBuf =
SM->getCharacterData(LocEnd);
4726 if (isa<TypeOfExprType>(TypePtr)) {
4727 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4729 std::string TypeAsString =
"(";
4730 RewriteBlockPointerType(TypeAsString, QT);
4731 TypeAsString +=
")";
4732 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4736 const char *argPtr = startBuf;
4738 while (*argPtr++ && (argPtr < endBuf)) {
4743 ReplaceText(LocStart, 1,
"*");
4749void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4751 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4752 CastKind != CK_AnyPointerToBlockPointerCast)
4756 (void)convertBlockPointerToFunctionPointer(QT);
4757 std::string TypeString(QT.
getAsString(Context->getPrintingPolicy()));
4758 std::string Str =
"(";
4764void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4766 unsigned parenCount = 0;
4769 const char *startBuf =
SM->getCharacterData(DeclLoc);
4770 const char *startArgList = strchr(startBuf,
'(');
4772 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4777 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4779 const char *argPtr = startArgList;
4781 while (*argPtr++ && parenCount) {
4786 ReplaceText(DeclLoc, 1,
"*");
4798bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4805 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4810 if (isTopLevelBlockPointerType(I))
4816bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4823 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4828 if (I->isObjCQualifiedIdType())
4830 if (I->isObjCObjectPointerType() &&
4831 I->getPointeeType()->isObjCQualifiedInterfaceType())
4839void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4840 const char *&RParen) {
4841 const char *argPtr = strchr(Name,
'(');
4842 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4846 unsigned parenCount = 1;
4848 while (*argPtr && parenCount) {
4850 case '(': parenCount++;
break;
4851 case ')': parenCount--;
break;
4854 if (parenCount) argPtr++;
4856 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4860void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4862 RewriteBlockPointerFunctionArgs(FD);
4868 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4871 DeclT = TDD->getUnderlyingType();
4872 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4875 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4877 const char *startBuf =
SM->getCharacterData(DeclLoc);
4878 const char *endBuf = startBuf;
4880 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4884 unsigned OrigLength=0;
4887 if (*startBuf ==
'^') {
4893 while (*startBuf !=
')') {
4901 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4902 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4906 startBuf =
SM->getCharacterData(DeclLoc);
4907 const char *argListBegin, *argListEnd;
4908 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4909 while (argListBegin < argListEnd) {
4910 if (*argListBegin ==
'^')
4912 else if (*argListBegin ==
'<') {
4914 buf += *argListBegin++;
4916 while (*argListBegin !=
'>') {
4917 buf += *argListBegin++;
4920 buf += *argListBegin;
4924 buf += *argListBegin;
4931 ReplaceText(Start, OrigLength, buf);
4954std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4957 if (CopyDestroyCache.count(flag))
4959 CopyDestroyCache.insert(flag);
4960 S =
"static void __Block_byref_id_object_copy_";
4962 S +=
"(void *dst, void *src) {\n";
4967 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4968 unsigned VoidPtrSize =
4969 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4971 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4972 S +=
" _Block_object_assign((char*)dst + ";
4973 S += utostr(offset);
4974 S +=
", *(void * *) ((char*)src + ";
4975 S += utostr(offset);
4980 S +=
"static void __Block_byref_id_object_dispose_";
4982 S +=
"(void *src) {\n";
4983 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4984 S += utostr(offset);
5009void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5018 const char *startBuf =
SM->getCharacterData(DeclLoc);
5020 X =
SM->getExpansionLoc(
X);
5021 const char *endBuf =
SM->getCharacterData(
X);
5023 std::string ByrefType;
5024 RewriteByRefString(ByrefType, Name, ND,
true);
5025 ByrefType +=
" {\n";
5026 ByrefType +=
" void *__isa;\n";
5027 RewriteByRefString(ByrefType, Name, ND);
5028 ByrefType +=
" *__forwarding;\n";
5029 ByrefType +=
" int __flags;\n";
5030 ByrefType +=
" int __size;\n";
5034 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
5035 if (HasCopyAndDispose) {
5036 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5037 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5041 (void)convertBlockPointerToFunctionPointer(T);
5042 T.getAsStringInternal(Name, Context->getPrintingPolicy());
5044 ByrefType +=
" " + Name +
";\n";
5045 ByrefType +=
"};\n";
5049 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5051 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5054 InsertText(FunLocStart, ByrefType);
5060 if (HasCopyAndDispose) {
5068 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5076 bool hasInit = (ND->
getInit() !=
nullptr);
5087 if (HasCopyAndDispose)
5091 RewriteByRefString(ByrefType, Name, ND);
5092 std::string ForwardingCastType(
"(");
5093 ForwardingCastType += ByrefType +
" *)";
5094 ByrefType +=
" " + Name +
" = {(void*)";
5095 ByrefType += utostr(isa);
5096 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5097 ByrefType += utostr(flags);
5099 ByrefType +=
"sizeof(";
5100 RewriteByRefString(ByrefType, Name, ND);
5102 if (HasCopyAndDispose) {
5103 ByrefType +=
", __Block_byref_id_object_copy_";
5104 ByrefType += utostr(flag);
5105 ByrefType +=
", __Block_byref_id_object_dispose_";
5106 ByrefType += utostr(flag);
5114 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5115 const char *commaBuf = startDeclBuf;
5116 while (*commaBuf !=
',')
5118 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5120 startBuf = commaBuf;
5124 ByrefType +=
"};\n";
5125 unsigned nameSize = Name.size();
5130 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5137 startLoc = ECE->getLParenLoc();
5139 startLoc =
E->getBeginLoc();
5140 startLoc =
SM->getExpansionLoc(startLoc);
5141 endBuf =
SM->getCharacterData(startLoc);
5142 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5144 const char separator = lastDecl ?
';' :
',';
5145 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5146 const char *separatorBuf = strchr(startInitializerBuf, separator);
5147 assert((*separatorBuf == separator) &&
5148 "RewriteByRefVar: can't find ';' or ','");
5152 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5156void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5158 GetBlockDeclRefExprs(Exp->
getBody());
5159 if (BlockDeclRefs.size()) {
5161 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5162 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5163 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5164 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5165 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5169 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5170 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5171 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5172 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5173 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5177 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5178 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5179 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5180 BlockDeclRefs[i]->getType()->isBlockPointerType())
5181 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5185FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5187 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5197 Blocks.push_back(Exp);
5199 CollectBlockDeclRefInfo(Exp);
5202 int countOfInnerDecls = 0;
5203 if (!InnerBlockDeclRefs.empty()) {
5204 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5207 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5211 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5212 BlockDeclRefs.push_back(Exp);
5213 BlockByCopyDeclsPtrSet.insert(VD);
5214 BlockByCopyDecls.push_back(VD);
5216 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5217 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5218 BlockDeclRefs.push_back(Exp);
5219 BlockByRefDeclsPtrSet.insert(VD);
5220 BlockByRefDecls.push_back(VD);
5224 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5225 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5226 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5227 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5228 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5230 InnerDeclRefsCount.push_back(countOfInnerDecls);
5232 std::string FuncName;
5236 else if (CurMethodDef)
5237 BuildUniqueMethodName(FuncName, CurMethodDef);
5238 else if (GlobalVarDecl)
5241 bool GlobalBlockExpr =
5244 if (GlobalBlockExpr && !GlobalVarDecl) {
5246 GlobalBlockExpr =
false;
5249 std::string BlockNumber = utostr(Blocks.size()-1);
5251 std::string
Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5254 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5255 QualType FType = Context->getPointerType(BFT);
5263 if (GlobalBlockExpr)
5267 Tag += FuncName +
"_block_impl_" + BlockNumber;
5269 FD = SynthBlockInitFunctionDecl(Tag);
5276 FD = SynthBlockInitFunctionDecl(Func);
5281 InitExprs.push_back(castExpr);
5284 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5286 VarDecl *NewVD = VarDecl::Create(
5288 &Context->Idents.get(DescData), Context->VoidPtrTy,
nullptr, SC_Static);
5291 new (Context)
DeclRefExpr(*Context, NewVD,
false, Context->VoidPtrTy,
5293 UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue,
5295 InitExprs.push_back(DescRefExpr);
5298 if (BlockDeclRefs.size()) {
5302 E = BlockByCopyDecls.end(); I !=
E; ++I) {
5303 if (isObjCType((*I)->getType())) {
5305 FD = SynthBlockInitFunctionDecl((*I)->getName());
5308 if (HasLocalVariableExternalStorage(*I)) {
5310 QT = Context->getPointerType(QT);
5311 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5312 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5316 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5317 FD = SynthBlockInitFunctionDecl((*I)->getName());
5320 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5323 FD = SynthBlockInitFunctionDecl((*I)->getName());
5326 if (HasLocalVariableExternalStorage(*I)) {
5328 QT = Context->getPointerType(QT);
5329 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5330 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5336 InitExprs.push_back(Exp);
5340 E = BlockByRefDecls.end(); I !=
E; ++I) {
5343 std::string RecName;
5344 RewriteByRefString(RecName, Name, ND,
true);
5346 +
sizeof(
"struct"));
5348 RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
5350 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5351 QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5353 FD = SynthBlockInitFunctionDecl((*I)->getName());
5356 bool isNestedCapturedVar =
false;
5357 for (
const auto &CI : block->
captures()) {
5358 const VarDecl *variable = CI.getVariable();
5359 if (variable == ND && CI.isNested()) {
5360 assert(CI.isByRef() &&
5361 "SynthBlockInitExpr - captured block variable is not byref");
5362 isNestedCapturedVar =
true;
5368 if (!isNestedCapturedVar)
5369 Exp = UnaryOperator::Create(
5370 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5371 Context->getPointerType(Exp->
getType()), VK_PRValue, OK_Ordinary,
5373 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5374 InitExprs.push_back(Exp);
5377 if (ImportedBlockDecls.size()) {
5381 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5382 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag),
5384 InitExprs.push_back(FlagExp);
5386 NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
5389 if (GlobalBlockExpr) {
5390 assert (!GlobalConstructionExp &&
5391 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5392 GlobalConstructionExp = NewRep;
5396 NewRep = UnaryOperator::Create(
5397 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5398 Context->getPointerType(NewRep->
getType()), VK_PRValue, OK_Ordinary,
5400 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5406 BlockDeclRefs.clear();
5407 BlockByRefDecls.clear();
5408 BlockByRefDeclsPtrSet.clear();
5409 BlockByCopyDecls.clear();
5410 BlockByCopyDeclsPtrSet.clear();
5411 ImportedBlockDecls.clear();
5415bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5417 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5418 return CS->getElement() == DS;
5426Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5427 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5428 isa<DoStmt>(S) || isa<ForStmt>(S))
5430 else if (isa<ObjCForCollectionStmt>(S)) {
5432 ObjCBcLabelNo.push_back(++BcLabelCount);
5439 return RewritePropertyOrImplicitSetter(PseudoOp);
5441 return RewritePropertyOrImplicitGetter(PseudoOp);
5443 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5444 return RewriteObjCIvarRefExpr(IvarRefExpr);
5446 else if (isa<OpaqueValueExpr>(S))
5447 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5452 for (
Stmt *&childStmt : S->children())
5454 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5456 childStmt = newStmt;
5460 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5463 InnerContexts.insert(BE->getBlockDecl());
5464 ImportedLocalExternalDecls.clear();
5465 GetInnerBlockDeclRefExprs(BE->getBody(),
5466 InnerBlockDeclRefs, InnerContexts);
5468 Stmt *SaveCurrentBody = CurrentBody;
5469 CurrentBody = BE->getBody();
5470 PropParentMap =
nullptr;
5476 bool saveDisableReplaceStmt = DisableReplaceStmt;
5477 DisableReplaceStmt =
false;
5478 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5479 DisableReplaceStmt = saveDisableReplaceStmt;
5480 CurrentBody = SaveCurrentBody;
5481 PropParentMap =
nullptr;
5482 ImportedLocalExternalDecls.clear();
5484 std::string Str =
Rewrite.getRewrittenText(BE->getSourceRange());
5485 RewrittenBlockExprs[BE] = Str;
5487 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5490 ReplaceStmt(S, blockTranscribed);
5491 return blockTranscribed;
5495 return RewriteAtEncode(AtEncode);
5498 return RewriteAtSelector(AtSelector);
5501 return RewriteObjCStringLiteral(AtString);
5504 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5507 return RewriteObjCBoxedExpr(BoxedExpr);
5510 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5513 dyn_cast<ObjCDictionaryLiteral>(S))
5514 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5522 const char *startBuf =
SM->getCharacterData(startLoc);
5523 const char *endBuf =
SM->getCharacterData(endLoc);
5525 std::string messString;
5526 messString +=
"// ";
5527 messString.append(startBuf, endBuf-startBuf+1);
5536 return RewriteMessageExpr(MessExpr);
5540 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5541 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5545 return RewriteObjCTryStmt(StmtTry);
5548 return RewriteObjCSynchronizedStmt(StmtTry);
5551 return RewriteObjCThrowStmt(StmtThrow);
5554 return RewriteObjCProtocolExpr(ProtocolExp);
5557 dyn_cast<ObjCForCollectionStmt>(S))
5558 return RewriteObjCForCollectionStmt(StmtForCollection,
5561 dyn_cast<BreakStmt>(S))
5562 return RewriteBreakStmt(StmtBreakStmt);
5564 dyn_cast<ContinueStmt>(S))
5565 return RewriteContinueStmt(StmtContinueStmt);
5569 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5579 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5580 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5586 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5587 if (isTopLevelBlockPointerType(ND->
getType()))
5588 RewriteBlockPointerDecl(ND);
5590 CheckFunctionPointerDecl(ND->
getType(), ND);
5591 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5592 if (VD->
hasAttr<BlocksAttr>()) {
5593 static unsigned uniqueByrefDeclCount = 0;
5594 assert(!BlockByRefDeclNo.count(ND) &&
5595 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5596 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5597 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5600 RewriteTypeOfDecl(VD);
5604 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5605 RewriteBlockPointerDecl(TD);
5607 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5613 RewriteObjCQualifiedInterfaceTypes(CE);
5615 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5616 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5617 assert(!Stmts.empty() &&
"Statement stack is empty");
5618 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5619 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5620 &&
"Statement stack mismatch");
5624 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5626 if (VD->
hasAttr<BlocksAttr>())
5627 return RewriteBlockDeclRefExpr(DRE);
5628 if (HasLocalVariableExternalStorage(VD))
5629 return RewriteLocalVariableExternalStorage(DRE);
5632 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5634 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5635 ReplaceStmt(S, BlockCall);
5640 RewriteCastExpr(CE);
5643 RewriteImplicitCastObjCExpr(ICE);
5653 llvm::raw_string_ostream Buf(SStr);
5654 Replacement->printPretty(Buf);
5655 const std::string &Str = Buf.str();
5657 printf(
"CAST = %s\n", &Str[0]);
5667void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5668 for (
auto *FD : RD->
fields()) {
5669 if (isTopLevelBlockPointerType(FD->
getType()))
5670 RewriteBlockPointerDecl(FD);
5673 RewriteObjCQualifiedInterfaceTypes(FD);
5679void RewriteModernObjC::HandleDeclInMainFile(
Decl *
D) {
5680 switch (
D->getKind()) {
5681 case Decl::Function: {
5689 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5696 CurFunctionDef = FD;
5699 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5701 CurrentBody =
nullptr;
5702 if (PropParentMap) {
5703 delete PropParentMap;
5704 PropParentMap =
nullptr;
5708 InsertBlockLiteralsWithinFunction(FD);
5709 RewriteLineDirective(
D);
5710 CurFunctionDef =
nullptr;
5714 case Decl::ObjCMethod: {
5720 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5722 CurrentBody =
nullptr;
5723 if (PropParentMap) {
5724 delete PropParentMap;
5725 PropParentMap =
nullptr;
5727 InsertBlockLiteralsWithinMethod(MD);
5728 RewriteLineDirective(
D);
5729 CurMethodDef =
nullptr;
5733 case Decl::ObjCImplementation: {
5735 ClassImplementation.push_back(CI);
5738 case Decl::ObjCCategoryImpl: {
5740 CategoryImplementation.push_back(CI);
5745 RewriteObjCQualifiedInterfaceTypes(VD);
5746 if (isTopLevelBlockPointerType(VD->
getType()))
5747 RewriteBlockPointerDecl(VD);
5749 CheckFunctionPointerDecl(VD->
getType(), VD);
5752 RewriteCastExpr(CE);
5758 RewriteRecordBody(RD);
5763 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5764 CurrentBody =
nullptr;
5765 if (PropParentMap) {
5766 delete PropParentMap;
5767 PropParentMap =
nullptr;
5770 GlobalVarDecl =
nullptr;
5774 RewriteCastExpr(CE);
5779 case Decl::TypeAlias:
5780 case Decl::Typedef: {
5782 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5783 RewriteBlockPointerDecl(TD);
5785 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5787 RewriteObjCQualifiedInterfaceTypes(TD);
5791 case Decl::CXXRecord:
5792 case Decl::Record: {
5795 RewriteRecordBody(RD);
5807static void Write_ProtocolExprReferencedMetadata(
ASTContext *Context,
5809 std::string &Result) {
5811 if (Context->getLangOpts().MicrosoftExt)
5812 Result +=
"static ";
5813 Result +=
"struct _protocol_t *";
5814 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5821void RewriteModernObjC::HandleTranslationUnit(
ASTContext &C) {
5827 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5832 HandleTopLevelSingleDecl(FDecl);
5838 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5839 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5842 InsertText(
SM->getLocForStartOfFile(MainFileID), Preamble,
false);
5844 if (ClassImplementation.size() || CategoryImplementation.size())
5845 RewriteImplementations();
5847 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5853 RewriteInterfaceDecl(CDecl);
5859 Rewrite.getRewriteBufferFor(MainFileID)) {
5861 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5863 llvm::errs() <<
"No changes\n";
5866 if (ClassImplementation.size() || CategoryImplementation.size() ||
5867 ProtocolExprDecls.size()) {
5869 std::string ResultStr;
5870 RewriteMetaDataIntoBuffer(ResultStr);
5872 *OutFile << ResultStr;
5876 std::string ResultStr;
5877 WriteImageInfo(ResultStr);
5878 *OutFile << ResultStr;
5883void RewriteModernObjC::Initialize(
ASTContext &context) {
5884 InitializeCommon(context);
5894 Preamble +=
"struct objc_selector; struct objc_class;\n";
5895 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5896 Preamble +=
"\n\tstruct objc_object *superClass; ";
5898 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5899 Preamble +=
": object(o), superClass(s) {} ";
5902 if (LangOpts.MicrosoftExt) {
5905 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5906 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5907 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5908 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5909 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5911 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5912 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5913 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5914 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5918 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5919 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5920 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5923 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5924 Preamble +=
"typedef struct objc_object Protocol;\n";
5925 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5927 if (LangOpts.MicrosoftExt) {
5928 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5929 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5932 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5934 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5935 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5936 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5937 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5938 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5940 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5942 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5943 Preamble +=
"(struct objc_class *);\n";
5944 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5946 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5948 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5949 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5950 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5952 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5954 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5956 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5957 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5958 Preamble +=
"unsigned long state;\n\t";
5959 Preamble +=
"void **itemsPtr;\n\t";
5960 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5961 Preamble +=
"unsigned long extra[5];\n};\n";
5962 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5963 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5965 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5966 Preamble +=
"struct __NSConstantStringImpl {\n";
5971 Preamble +=
" long long length;\n";
5976 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5977 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5979 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5981 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5984 Preamble +=
"#ifndef BLOCK_IMPL\n";
5985 Preamble +=
"#define BLOCK_IMPL\n";
5986 Preamble +=
"struct __block_impl {\n";
5992 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5993 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5994 Preamble +=
"extern \"C\" __declspec(dllexport) "
5995 "void _Block_object_assign(void *, const void *, const int);\n";
5996 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5997 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5998 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6000 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6001 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6002 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6003 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6006 if (LangOpts.MicrosoftExt) {
6007 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6008 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6009 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6010 Preamble +=
"#define __attribute__(X)\n";
6025 Preamble +=
"\n#include <stdarg.h>\n";
6026 Preamble +=
"struct __NSContainer_literal {\n";
6028 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6030 Preamble +=
"\tva_start(marker, count);\n";
6031 Preamble +=
"\tarr = new void *[count];\n";
6032 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6033 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6034 Preamble +=
"\tva_end( marker );\n";
6036 Preamble +=
" ~__NSContainer_literal() {\n";
6042 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6043 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6044 Preamble +=
"struct __AtAutoreleasePool {\n";
6045 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6046 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6047 Preamble +=
" void * atautoreleasepoolobj;\n";
6052 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6057void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6058 std::string &Result) {
6059 Result +=
"__OFFSETOFIVAR__(struct ";
6061 if (LangOpts.MicrosoftExt)
6065 ObjCIvarBitfieldGroupDecl(ivar, Result);
6173static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6174 static bool meta_data_declared =
false;
6175 if (meta_data_declared)
6178 Result +=
"\nstruct _prop_t {\n";
6179 Result +=
"\tconst char *name;\n";
6180 Result +=
"\tconst char *attributes;\n";
6183 Result +=
"\nstruct _protocol_t;\n";
6185 Result +=
"\nstruct _objc_method {\n";
6186 Result +=
"\tstruct objc_selector * _cmd;\n";
6187 Result +=
"\tconst char *method_type;\n";
6188 Result +=
"\tvoid *_imp;\n";
6191 Result +=
"\nstruct _protocol_t {\n";
6192 Result +=
"\tvoid * isa; // NULL\n";
6193 Result +=
"\tconst char *protocol_name;\n";
6194 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6195 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6196 Result +=
"\tconst struct method_list_t *class_methods;\n";
6197 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6198 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6199 Result +=
"\tconst struct _prop_list_t * properties;\n";
6200 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6201 Result +=
"\tconst unsigned int flags; // = 0\n";
6202 Result +=
"\tconst char ** extendedMethodTypes;\n";
6205 Result +=
"\nstruct _ivar_t {\n";
6206 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6207 Result +=
"\tconst char *name;\n";
6208 Result +=
"\tconst char *type;\n";
6209 Result +=
"\tunsigned int alignment;\n";
6210 Result +=
"\tunsigned int size;\n";
6213 Result +=
"\nstruct _class_ro_t {\n";
6214 Result +=
"\tunsigned int flags;\n";
6215 Result +=
"\tunsigned int instanceStart;\n";
6216 Result +=
"\tunsigned int instanceSize;\n";
6217 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6218 if (Triple.getArch() == llvm::Triple::x86_64)
6219 Result +=
"\tunsigned int reserved;\n";
6220 Result +=
"\tconst unsigned char *ivarLayout;\n";
6221 Result +=
"\tconst char *name;\n";
6222 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6223 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6224 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6225 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6226 Result +=
"\tconst struct _prop_list_t *properties;\n";
6229 Result +=
"\nstruct _class_t {\n";
6230 Result +=
"\tstruct _class_t *isa;\n";
6231 Result +=
"\tstruct _class_t *superclass;\n";
6232 Result +=
"\tvoid *cache;\n";
6233 Result +=
"\tvoid *vtable;\n";
6234 Result +=
"\tstruct _class_ro_t *ro;\n";
6237 Result +=
"\nstruct _category_t {\n";
6238 Result +=
"\tconst char *name;\n";
6239 Result +=
"\tstruct _class_t *cls;\n";
6240 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6241 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6242 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6243 Result +=
"\tconst struct _prop_list_t *properties;\n";
6246 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6247 Result +=
"#pragma warning(disable:4273)\n";
6248 meta_data_declared =
true;
6251static void Write_protocol_list_t_TypeDecl(std::string &Result,
6252 long super_protocol_count) {
6253 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6254 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6255 Result +=
"\tstruct _protocol_t *super_protocols[";
6256 Result += utostr(super_protocol_count); Result +=
"];\n";
6260static void Write_method_list_t_TypeDecl(std::string &Result,
6261 unsigned int method_count) {
6262 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6263 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6264 Result +=
"\tunsigned int method_count;\n";
6265 Result +=
"\tstruct _objc_method method_list[";
6266 Result += utostr(method_count); Result +=
"];\n";
6270static void Write__prop_list_t_TypeDecl(std::string &Result,
6271 unsigned int property_count) {
6272 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6273 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6274 Result +=
"\tunsigned int count_of_properties;\n";
6275 Result +=
"\tstruct _prop_t prop_list[";
6276 Result += utostr(property_count); Result +=
"];\n";
6280static void Write__ivar_list_t_TypeDecl(std::string &Result,
6281 unsigned int ivar_count) {
6282 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6283 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6284 Result +=
"\tunsigned int count;\n";
6285 Result +=
"\tstruct _ivar_t ivar_list[";
6286 Result += utostr(ivar_count); Result +=
"];\n";
6290static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6293 StringRef ProtocolName) {
6294 if (SuperProtocols.size() > 0) {
6295 Result +=
"\nstatic ";
6296 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6297 Result +=
" "; Result += VarName;
6298 Result += ProtocolName;
6299 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6300 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6301 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6303 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6313static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6317 StringRef TopLevelDeclName,
6319 if (Methods.size() > 0) {
6320 Result +=
"\nstatic ";
6321 Write_method_list_t_TypeDecl(Result, Methods.size());
6322 Result +=
" "; Result += VarName;
6323 Result += TopLevelDeclName;
6324 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6325 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6326 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6327 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6330 Result +=
"\t{{(struct objc_selector *)\"";
6332 Result +=
"\t{(struct objc_selector *)\"";
6333 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6335 std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(MD);
6336 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6341 Result +=
"(void *)";
6342 Result += RewriteObj.MethodInternalNames[MD];
6353static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6356 const Decl *Container,
6358 StringRef ProtocolName) {
6359 if (Properties.size() > 0) {
6360 Result +=
"\nstatic ";
6361 Write__prop_list_t_TypeDecl(Result, Properties.size());
6362 Result +=
" "; Result += VarName;
6363 Result += ProtocolName;
6364 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6365 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6366 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6367 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6373 Result += PropDecl->
getName(); Result +=
"\",";
6374 std::string PropertyTypeString =
6375 Context->getObjCEncodingForPropertyDecl(PropDecl, Container);
6376 std::string QuotePropertyTypeString;
6377 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6378 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6393 OBJC2_CLS_HIDDEN = 0x10,
6394 CLS_EXCEPTION = 0x20,
6397 CLS_HAS_IVAR_RELEASER = 0x40,
6399 CLS_COMPILED_BY_ARC = 0x80
6402static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6404 const std::string &InstanceStart,
6405 const std::string &InstanceSize,
6411 StringRef ClassName) {
6412 Result +=
"\nstatic struct _class_ro_t ";
6413 Result += VarName; Result += ClassName;
6414 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6416 Result += llvm::utostr(flags); Result +=
", ";
6417 Result += InstanceStart; Result +=
", ";
6418 Result += InstanceSize; Result +=
", \n";
6420 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6421 if (Triple.getArch() == llvm::Triple::x86_64)
6423 Result +=
"(unsigned int)0, \n\t";
6425 Result +=
"0, \n\t";
6426 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6427 bool metaclass = ((flags & CLS_META) != 0);
6428 if (baseMethods.size() > 0) {
6429 Result +=
"(const struct _method_list_t *)&";
6431 Result +=
"_OBJC_$_CLASS_METHODS_";
6433 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6434 Result += ClassName;
6438 Result +=
"0, \n\t";
6440 if (!metaclass && baseProtocols.size() > 0) {
6441 Result +=
"(const struct _objc_protocol_list *)&";
6442 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6446 Result +=
"0, \n\t";
6448 if (!metaclass && ivars.size() > 0) {
6449 Result +=
"(const struct _ivar_list_t *)&";
6450 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6454 Result +=
"0, \n\t";
6457 Result +=
"0, \n\t";
6458 if (!metaclass && Properties.size() > 0) {
6459 Result +=
"(const struct _prop_list_t *)&";
6460 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6469static void Write_class_t(
ASTContext *Context, std::string &Result,
6483 if (metaclass && rootClass) {
6486 Result +=
"extern \"C\" ";
6488 Result +=
"__declspec(dllexport) ";
6490 Result +=
"__declspec(dllimport) ";
6492 Result +=
"struct _class_t OBJC_CLASS_$_";
6500 Result +=
"extern \"C\" ";
6502 Result +=
"__declspec(dllexport) ";
6504 Result +=
"__declspec(dllimport) ";
6506 Result +=
"struct _class_t ";
6511 if (metaclass && RootClass != SuperClass) {
6512 Result +=
"extern \"C\" ";
6514 Result +=
"__declspec(dllexport) ";
6516 Result +=
"__declspec(dllimport) ";
6518 Result +=
"struct _class_t ";
6525 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6527 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6531 Result +=
"0, // &"; Result += VarName;
6534 Result +=
"0, // &"; Result += VarName;
6539 Result +=
"0, // &"; Result += VarName;
6547 Result +=
"0, // &OBJC_METACLASS_$_";
6551 Result +=
"0, // &"; Result += VarName;
6558 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6559 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6561 Result +=
"&_OBJC_METACLASS_RO_$_";
6563 Result +=
"&_OBJC_CLASS_RO_$_";
6565 Result +=
",\n};\n";
6575 Result +=
"static void OBJC_CLASS_SETUP_$_";
6577 Result +=
"(void ) {\n";
6579 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6583 Result +=
".superclass = ";
6585 Result +=
"&OBJC_CLASS_$_";
6587 Result +=
"&OBJC_METACLASS_$_";
6592 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6595 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6600 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6605 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6609static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6610 std::string &Result,
6617 StringRef CatName = CatDecl->
getName();
6618 StringRef ClassName = ClassDecl->
getName();
6622 Result +=
"extern \"C\" ";
6624 Result +=
"__declspec(dllexport) ";
6626 Result +=
"__declspec(dllimport) ";
6628 Result +=
"struct _class_t ";
6629 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6632 Result +=
"\nstatic struct _category_t ";
6633 Result +=
"_OBJC_$_CATEGORY_";
6634 Result += ClassName; Result +=
"_$_"; Result += CatName;
6635 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6637 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6638 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6640 if (InstanceMethods.size() > 0) {
6641 Result +=
"\t(const struct _method_list_t *)&";
6642 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6643 Result += ClassName; Result +=
"_$_"; Result += CatName;
6649 if (ClassMethods.size() > 0) {
6650 Result +=
"\t(const struct _method_list_t *)&";
6651 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6652 Result += ClassName; Result +=
"_$_"; Result += CatName;
6658 if (RefedProtocols.size() > 0) {
6659 Result +=
"\t(const struct _protocol_list_t *)&";
6660 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6661 Result += ClassName; Result +=
"_$_"; Result += CatName;
6667 if (ClassProperties.size() > 0) {
6668 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6669 Result += ClassName; Result +=
"_$_"; Result += CatName;
6678 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6682 Result +=
"(void ) {\n";
6683 Result +=
"\t_OBJC_$_CATEGORY_";
6687 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6691static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6695 StringRef ProtocolName) {
6696 if (Methods.size() == 0)
6699 Result +=
"\nstatic const char *";
6700 Result += VarName; Result += ProtocolName;
6701 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6703 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6705 std::string MethodTypeString =
6706 Context->getObjCEncodingForMethodDecl(MD,
true);
6707 std::string QuoteMethodTypeString;
6708 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6709 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6718static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6720 std::string &Result,
6735 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6737 if (Context->getLangOpts().MicrosoftExt)
6738 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6740 if (!Context->getLangOpts().MicrosoftExt ||
6743 Result +=
"extern \"C\" unsigned long int ";
6745 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6746 if (Ivars[i]->isBitField())
6747 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6749 WriteInternalIvarName(CDecl, IvarDecl, Result);
6750 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6752 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6754 if (Ivars[i]->isBitField()) {
6756 SKIP_BITFIELDS(i , e, Ivars);
6761static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6766 if (OriginalIvars.size() > 0) {
6767 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6772 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6773 if (OriginalIvars[i]->isBitField()) {
6774 Ivars.push_back(OriginalIvars[i]);
6776 SKIP_BITFIELDS(i , e, OriginalIvars);
6779 Ivars.push_back(OriginalIvars[i]);
6782 Result +=
"\nstatic ";
6783 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6784 Result +=
" "; Result += VarName;
6786 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6787 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6788 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6789 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6795 Result +=
"(unsigned long int *)&";
6796 if (Ivars[i]->isBitField())
6797 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6799 WriteInternalIvarName(CDecl, IvarDecl, Result);
6803 if (Ivars[i]->isBitField())
6804 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6806 Result += IvarDecl->
getName();
6811 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6813 std::string IvarTypeString, QuoteIvarTypeString;
6814 Context->getObjCEncodingForType(IVQT, IvarTypeString,
6816 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6817 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6821 unsigned Align = Context->getTypeAlign(IVQT)/8;
6822 Align = llvm::Log2_32(Align);
6823 Result += llvm::utostr(Align); Result +=
", ";
6825 Result += llvm::utostr(
Size.getQuantity());
6836void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6837 std::string &Result) {
6842 WriteModernMetadataDeclarations(Context, Result);
6849 RewriteObjCProtocolMetaData(I, Result);
6852 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6853 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6856 OptInstanceMethods.push_back(MD);
6858 InstanceMethods.push_back(MD);
6864 OptClassMethods.push_back(MD);
6866 ClassMethods.push_back(MD);
6869 std::vector<ObjCMethodDecl *> AllMethods;
6870 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6871 AllMethods.push_back(InstanceMethods[i]);
6872 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6873 AllMethods.push_back(ClassMethods[i]);
6874 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6875 AllMethods.push_back(OptInstanceMethods[i]);
6876 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6877 AllMethods.push_back(OptClassMethods[i]);
6879 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6881 "_OBJC_PROTOCOL_METHOD_TYPES_",
6885 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6886 "_OBJC_PROTOCOL_REFS_",
6889 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6890 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6893 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6894 "_OBJC_PROTOCOL_CLASS_METHODS_",
6897 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6898 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6901 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6902 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6908 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
6910 "_OBJC_PROTOCOL_PROPERTIES_",
6915 if (LangOpts.MicrosoftExt)
6916 Result +=
"static ";
6917 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6919 Result +=
" __attribute__ ((used)) = {\n";
6921 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6922 if (SuperProtocols.size() > 0) {
6923 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6928 if (InstanceMethods.size() > 0) {
6929 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6935 if (ClassMethods.size() > 0) {
6936 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6942 if (OptInstanceMethods.size() > 0) {
6943 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6949 if (OptClassMethods.size() > 0) {
6950 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6956 if (ProtocolProperties.size() > 0) {
6957 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6963 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6966 if (AllMethods.size() > 0) {
6967 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6972 Result +=
"\t0\n};\n";
6974 if (LangOpts.MicrosoftExt)
6975 Result +=
"static ";
6976 Result +=
"struct _protocol_t *";
6977 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6983 llvm_unreachable(
"protocol already synthesized");
6991 if (OID->
hasAttr<ObjCExceptionAttr>())
6999 std::string &Result) {
7005 "Legacy implicit interface rewriting not supported in moder abi");
7007 WriteModernMetadataDeclarations(Context, Result);
7013 if (!IVD->getDeclName())
7015 IVars.push_back(IVD);
7018 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
7019 "_OBJC_$_INSTANCE_VARIABLES_",
7028 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7030 if (!Prop->getPropertyIvarDecl())
7036 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7037 InstanceMethods.push_back(Getter);
7041 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7042 InstanceMethods.push_back(Setter);
7045 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7046 "_OBJC_$_INSTANCE_METHODS_",
7051 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7052 "_OBJC_$_CLASS_METHODS_",
7057 std::vector<ObjCProtocolDecl *> RefedProtocols;
7060 E = Protocols.
end();
7062 RefedProtocols.push_back(*I);
7065 RewriteObjCProtocolMetaData(*I, Result);
7068 Write_protocol_list_initializer(Context, Result,
7070 "_OBJC_CLASS_PROTOCOLS_$_",
7076 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7078 "_OBJC_$_PROP_LIST_",
7082 uint32_t flags = CLS_META;
7083 std::string InstanceSize;
7084 std::string InstanceStart;
7088 flags |= OBJC2_CLS_HIDDEN;
7093 InstanceSize =
"sizeof(struct _class_t)";
7094 InstanceStart = InstanceSize;
7095 Write__class_ro_t_initializer(Context, Result, flags,
7096 InstanceStart, InstanceSize,
7101 "_OBJC_METACLASS_RO_$_",
7107 flags |= OBJC2_CLS_HIDDEN;
7110 flags |= CLS_EXCEPTION;
7116 InstanceSize.clear();
7117 InstanceStart.clear();
7118 if (!ObjCSynthesizedStructs.count(CDecl)) {
7120 InstanceStart =
"0";
7123 InstanceSize =
"sizeof(struct ";
7125 InstanceSize +=
"_IMPL)";
7129 RewriteIvarOffsetComputation(IVD, InstanceStart);
7132 InstanceStart = InstanceSize;
7134 Write__class_ro_t_initializer(Context, Result, flags,
7135 InstanceStart, InstanceSize,
7140 "_OBJC_CLASS_RO_$_",
7143 Write_class_t(Context, Result,
7144 "OBJC_METACLASS_$_",
7147 Write_class_t(Context, Result,
7151 if (ImplementationIsNonLazy(IDecl))
7152 DefinedNonLazyClasses.push_back(CDecl);
7155void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7156 int ClsDefCount = ClassImplementation.size();
7159 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7160 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7161 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7162 for (
int i = 0; i < ClsDefCount; i++) {
7165 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7166 Result += CDecl->
getName(); Result +=
",\n";
7171void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7172 int ClsDefCount = ClassImplementation.size();
7173 int CatDefCount = CategoryImplementation.size();
7176 for (
int i = 0; i < ClsDefCount; i++)
7177 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7179 RewriteClassSetupInitHook(Result);
7182 for (
int i = 0; i < CatDefCount; i++)
7183 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7185 RewriteCategorySetupInitHook(Result);
7187 if (ClsDefCount > 0) {
7188 if (LangOpts.MicrosoftExt)
7189 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7190 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7191 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7193 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7194 "regular,no_dead_strip\")))= {\n";
7195 for (
int i = 0; i < ClsDefCount; i++) {
7196 Result +=
"\t&OBJC_CLASS_$_";
7197 Result += ClassImplementation[i]->getNameAsString();
7202 if (!DefinedNonLazyClasses.empty()) {
7203 if (LangOpts.MicrosoftExt)
7204 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7205 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7206 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7207 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7214 if (CatDefCount > 0) {
7215 if (LangOpts.MicrosoftExt)
7216 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7217 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7218 Result += llvm::utostr(CatDefCount); Result +=
"]";
7220 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7221 "regular,no_dead_strip\")))= {\n";
7222 for (
int i = 0; i < CatDefCount; i++) {
7223 Result +=
"\t&_OBJC_$_CATEGORY_";
7225 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7227 Result += CategoryImplementation[i]->getNameAsString();
7233 if (!DefinedNonLazyCategories.empty()) {
7234 if (LangOpts.MicrosoftExt)
7235 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7236 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7237 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7238 Result +=
"\t&_OBJC_$_CATEGORY_";
7240 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7242 Result += DefinedNonLazyCategories[i]->getNameAsString();
7249void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7250 if (LangOpts.MicrosoftExt)
7251 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7253 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7255 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7261 std::string &Result) {
7262 WriteModernMetadataDeclarations(Context, Result);
7269 FullCategoryName +=
"_$_";
7278 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7280 if (!Prop->getPropertyIvarDecl())
7286 InstanceMethods.push_back(Getter);
7290 InstanceMethods.push_back(Setter);
7293 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7294 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7295 FullCategoryName,
true);
7299 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7300 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7301 FullCategoryName,
true);
7309 RewriteObjCProtocolMetaData(I, Result);
7311 Write_protocol_list_initializer(Context, Result,
7313 "_OBJC_CATEGORY_PROTOCOLS_$_",
7319 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7321 "_OBJC_$_PROP_LIST_",
7324 Write_category_t(*
this, Context, Result,
7333 if (ImplementationIsNonLazy(IDecl))
7334 DefinedNonLazyCategories.push_back(CDecl);
7337void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7338 int CatDefCount = CategoryImplementation.size();
7341 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7342 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7343 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7344 for (
int i = 0; i < CatDefCount; i++) {
7348 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7349 Result += ClassDecl->
getName();
7359template<
typename MethodIterator>
7360void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7361 MethodIterator MethodEnd,
7362 bool IsInstanceMethod,
7364 StringRef ClassName,
7365 std::string &Result) {
7366 if (MethodBegin == MethodEnd)
return;
7368 if (!objc_impl_method) {
7375 Result +=
"\nstruct _objc_method {\n";
7376 Result +=
"\tSEL _cmd;\n";
7377 Result +=
"\tchar *method_types;\n";
7378 Result +=
"\tvoid *_imp;\n";
7381 objc_impl_method =
true;
7392 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7394 if (LangOpts.MicrosoftExt) {
7395 if (IsInstanceMethod)
7396 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7398 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7400 Result +=
"static struct {\n";
7401 Result +=
"\tstruct _objc_method_list *next_method;\n";
7402 Result +=
"\tint method_count;\n";
7403 Result +=
"\tstruct _objc_method method_list[";
7404 Result += utostr(NumMethods);
7405 Result +=
"];\n} _OBJC_";
7408 Result +=
"_METHODS_";
7409 Result += ClassName;
7410 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7412 Result +=
"_meth\")))= ";
7413 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7415 Result +=
"\t,{{(SEL)\"";
7416 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7417 std::string MethodTypeString;
7418 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7420 Result += MethodTypeString;
7421 Result +=
"\", (void *)";
7422 Result += MethodInternalNames[*MethodBegin];
7424 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7425 Result +=
"\t ,{(SEL)\"";
7426 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7427 std::string MethodTypeString;
7428 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7430 Result += MethodTypeString;
7431 Result +=
"\", (void *)";
7432 Result += MethodInternalNames[*MethodBegin];
7435 Result +=
"\t }\n};\n";
7444 DisableReplaceStmtScope S(*
this);
7445 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7451 Expr *Replacement = IV;
7456 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7461 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7464 std::string IvarOffsetName;
7465 if (
D->isBitField())
7466 ObjCIvarBitfieldGroupOffset(
D, IvarOffsetName);
7468 WriteInternalIvarName(clsDeclared,
D, IvarOffsetName);
7470 ReferencedIvars[clsDeclared].insert(
D);
7474 Context->getPointerType(Context->CharTy),
7479 Context->UnsignedLongTy,
nullptr,
7482 DeclRefExpr(*Context, NewVD,
false, Context->UnsignedLongTy,
7485 *Context, castExpr, DRE, BO_Add,
7486 Context->getPointerType(Context->CharTy), VK_PRValue, OK_Ordinary,
7493 if (
D->isBitField())
7494 IvarT = GetGroupRecordTypeForObjCIvarBitfield(
D);
7501 auto *CDecl = cast<ObjCContainerDecl>(
D->getDeclContext());
7505 std::string RecName = std::string(CDecl->
getName());
7510 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
7511 unsigned UnsignedIntSize =
7512 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
7513 Expr *
Zero = IntegerLiteral::Create(*Context,
7514 llvm::APInt(UnsignedIntSize, 0),
7516 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7521 &Context->Idents.get(
D->getNameAsString()),
7526 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
7527 IvarT = Context->getDecltypeType(ME, ME->
getType());
7530 convertObjCTypeToCStyleType(IvarT);
7531 QualType castT = Context->getPointerType(IvarT);
7533 castExpr = NoTypeInfoCStyleCastExpr(Context,
7538 Expr *Exp = UnaryOperator::Create(
7539 const_cast<ASTContext &
>(*Context), castExpr, UO_Deref, IvarT,
7545 if (
D->isBitField()) {
7548 &Context->Idents.get(
D->getNameAsString()),
7549 D->getType(),
nullptr,
7553 MemberExpr::CreateImplicit(*Context, PE,
false, FD,
7554 FD->
getType(), VK_LValue, OK_Ordinary);
7562 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::@1659::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...
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Rewriter - This is the main interface to the rewrite buffers.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getByteLength() const
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
The top declaration context.
Represents a declaration of a type.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Expr * getUnderlyingExpr() const
A container of type source information.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isEnumeralType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCQualifiedInterfaceType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const Expr * getInit() const
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Defines the clang::TargetInfo interface.
@ BLOCK_BYREF_CURRENT_MAX
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
@ CF
Indicates that the tracked object is a CF object.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
@ OK_Ordinary
An ordinary object is located at an address in memory.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
CastKind
CastKind - The kind of operation required for a conversion.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
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 *.