22#include "clang/Config/config.h"
26#include "llvm/ADT/DenseSet.h"
27#include "llvm/ADT/SetVector.h"
28#include "llvm/ADT/SmallPtrSet.h"
29#include "llvm/ADT/StringExtras.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/raw_ostream.h"
34#if CLANG_ENABLE_OBJC_REWRITER
37using llvm::RewriteBuffer;
58 BLOCK_NEEDS_FREE = (1 << 24),
59 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
61 BLOCK_IS_GC = (1 << 27),
63 BLOCK_HAS_DESCRIPTOR = (1 << 29)
73 const char *MainFileStart, *MainFileEnd;
76 std::string InFileName;
77 std::unique_ptr<raw_ostream> OutFile;
82 Expr *GlobalConstructionExp;
83 unsigned RewriteFailedDiag;
84 unsigned GlobalBlockRewriteFailedDiag;
86 unsigned NumObjCStringLiterals;
87 VarDecl *ConstantStringClassReference;
93 unsigned TryFinallyContainsReturnDiag;
131 llvm::DenseSet<uint64_t> CopyDestroyCache;
143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
152 llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
162 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
166 bool SilenceRewriteMacroWarning;
167 bool GenerateLineInfo;
168 bool objc_impl_method;
170 bool DisableReplaceStmt;
171 class DisableReplaceStmtScope {
172 RewriteModernObjC &R;
176 DisableReplaceStmtScope(RewriteModernObjC &R)
177 : R(R), SavedValue(R.DisableReplaceStmt) {
178 R.DisableReplaceStmt =
true;
180 ~DisableReplaceStmtScope() {
181 R.DisableReplaceStmt = SavedValue;
187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
193 if (!
Class->isThisDeclarationADefinition()) {
194 RewriteForwardClassDecl(
D);
198 ObjCInterfacesSeen.push_back(Class);
204 if (!Proto->isThisDeclarationADefinition()) {
205 RewriteForwardProtocolDecl(
D);
215 if (FDecl->isThisDeclarationADefinition() &&
217 !FDecl->isTopLevelDeclInObjCContainer()) {
218 FunctionDefinitionsSeen.push_back(FDecl);
222 HandleTopLevelSingleDecl(*I);
227 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
230 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
231 RewriteBlockPointerDecl(TD);
232 else if (TD->getUnderlyingType()->isFunctionPointerType())
233 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
235 RewriteObjCQualifiedInterfaceTypes(TD);
240 void HandleTopLevelSingleDecl(
Decl *
D);
241 void HandleDeclInMainFile(
Decl *
D);
242 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
244 bool silenceMacroWarn,
bool LineInfo);
246 ~RewriteModernObjC()
override {}
248 void HandleTranslationUnit(
ASTContext &C)
override;
250 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
255 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
257 Stmt *ReplacingStmt = ReplacedNodes[Old];
261 if (DisableReplaceStmt)
273 llvm::raw_string_ostream S(SStr);
278 ReplacedNodes[Old] = New;
281 if (SilenceRewriteMacroWarning)
288 bool InsertAfter =
true) {
290 if (!
Rewrite.InsertText(
Loc, Str, InsertAfter) ||
291 SilenceRewriteMacroWarning)
294 Diags.
Report(Context->getFullLoc(
Loc), RewriteFailedDiag);
300 if (!
Rewrite.ReplaceText(Start, OrigLength, Str) ||
301 SilenceRewriteMacroWarning)
304 Diags.
Report(Context->getFullLoc(Start), RewriteFailedDiag);
309 void RewriteInclude();
310 void RewriteLineDirective(
const Decl *
D);
312 std::string &LineString);
316 const std::string &typedefString);
317 void RewriteImplementations();
322 void RewriteImplementationDecl(
Decl *Dcl);
325 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
327 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
336 void RewriteBlockPointerType(std::string& Str,
QualType Type);
337 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
339 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
340 void RewriteTypeOfDecl(
VarDecl *VD);
341 void RewriteObjCQualifiedInterfaceTypes(
Expr *
E);
346 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
367 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
372 void ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV, std::string &Result);
374 void ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV, std::string &Result);
376 void ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV, std::string &Result);
379 QualType SynthesizeBitfieldGroupStructType(
387 void RewriteBlockPointerDecl(
NamedDecl *VD);
388 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
394 std::string &Result);
396 void RewriteObjCFieldDecl(
FieldDecl *fieldDecl, std::string &Result);
398 bool &IsNamedDefinition);
399 void RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
400 std::string &Result);
402 bool RewriteObjCFieldDeclType(
QualType &
Type, std::string &Result);
405 std::string &Result);
407 void Initialize(
ASTContext &context)
override;
426 void SynthCountByEnumWithState(std::string &buf);
427 void SynthMsgSendFunctionDecl();
428 void SynthMsgSendSuperFunctionDecl();
429 void SynthMsgSendStretFunctionDecl();
430 void SynthMsgSendFpretFunctionDecl();
431 void SynthMsgSendSuperStretFunctionDecl();
432 void SynthGetClassFunctionDecl();
433 void SynthGetMetaClassFunctionDecl();
434 void SynthGetSuperClassFunctionDecl();
435 void SynthSelGetUidFunctionDecl();
436 void SynthSuperConstructorFunctionDecl();
439 template<
typename MethodIterator>
440 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
441 MethodIterator MethodEnd,
442 bool IsInstanceMethod,
445 std::string &Result);
447 std::string &Result);
449 std::string &Result);
450 void RewriteClassSetupInitHook(std::string &Result);
452 void RewriteMetaDataIntoBuffer(std::string &Result);
453 void WriteImageInfo(std::string &Result);
455 std::string &Result);
456 void RewriteCategorySetupInitHook(std::string &Result);
460 std::string &Result);
464 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
465 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
467 const std::string &Tag);
468 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i, StringRef funcName,
469 const std::string &Tag);
470 std::string SynthesizeBlockImpl(
BlockExpr *CE,
const std::string &Tag,
471 const std::string &Desc);
472 std::string SynthesizeBlockDescriptor(
const std::string &DescTag,
473 const std::string &ImplTag,
int i,
474 StringRef funcName,
unsigned hasCopy);
478 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
484 void WarnAboutReturnGotoStmts(
Stmt *S);
486 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
489 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
490 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
491 void GetBlockDeclRefExprs(
Stmt *S);
492 void GetInnerBlockDeclRefExprs(
Stmt *S,
494 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
498 bool isTopLevelBlockPointerType(
QualType T) {
499 return isa<BlockPointerType>(T);
505 bool convertBlockPointerToFunctionPointer(
QualType &T) {
506 if (isTopLevelBlockPointerType(T)) {
508 T = Context->getPointerType(BPT->getPointeeType());
514 bool convertObjCTypeToCStyleType(
QualType &T);
516 bool needToScanForQualifiers(
QualType T);
518 QualType getConstantStringStructType();
521 void convertToUnqualifiedObjCType(
QualType &T) {
523 bool isConst =
T.isConstQualified();
524 T = isConst ? Context->getObjCIdType().withConst()
525 : Context->getObjCIdType();
528 T = Context->getObjCClassType();
535 T = Context->getPointerType(T);
545 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
547 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
548 OCT == Context->getCanonicalType(Context->getObjCClassType()))
552 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
553 PT->getPointeeType()->isObjCQualifiedIdType())
559 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
560 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
561 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
562 const char *&RParen);
564 void QuoteDoublequotes(std::string &From, std::string &To) {
565 for (
unsigned i = 0; i < From.length(); i++) {
575 bool variadic =
false) {
576 if (result == Context->getObjCInstanceType())
577 result = Context->getObjCIdType();
580 return Context->getFunctionType(result, args, fpi);
587 return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue,
Kind,
E,
nullptr,
592 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
594 Selector LoadSel = Context->Selectors.getSelector(0, &II);
599 QualType StrType = Context->getConstantArrayType(
600 Context->CharTy, llvm::APInt(32, Str.size() + 1),
nullptr,
601 ArraySizeModifier::Normal, 0);
602 return StringLiteral::Create(*Context, Str, StringLiteralKind::Ordinary,
608void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
611 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
612 for (
const auto &I : fproto->param_types())
613 if (isTopLevelBlockPointerType(I)) {
615 RewriteBlockPointerDecl(
D);
621void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
623 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
627static bool IsHeaderFile(
const std::string &
Filename) {
628 std::string::size_type DotPos =
Filename.rfind(
'.');
630 if (DotPos == std::string::npos) {
635 std::string Ext =
Filename.substr(DotPos + 1);
638 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
641RewriteModernObjC::RewriteModernObjC(std::string inFile,
642 std::unique_ptr<raw_ostream> OS,
645 bool silenceMacroWarn,
bool LineInfo)
646 : Diags(
D), LangOpts(LOpts), InFileName(inFile), OutFile(
std::move(OS)),
647 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
648 IsHeader = IsHeaderFile(inFile);
650 "rewriting sub-expression within a macro (may not be correct)");
653 GlobalBlockRewriteFailedDiag = Diags.
getCustomDiagID(DiagnosticsEngine::Warning,
654 "rewriting block literal declared in global scope is not implemented");
657 DiagnosticsEngine::Warning,
658 "rewriter doesn't support user-specified control flow semantics "
659 "for @try/@finally (code may not execute properly)");
663 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
665 bool SilenceRewriteMacroWarning,
bool LineInfo) {
666 return std::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
667 LOpts, SilenceRewriteMacroWarning,
671void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
673 SM = &Context->getSourceManager();
674 TUDecl = Context->getTranslationUnitDecl();
675 MsgSendFunctionDecl =
nullptr;
676 MsgSendSuperFunctionDecl =
nullptr;
677 MsgSendStretFunctionDecl =
nullptr;
678 MsgSendSuperStretFunctionDecl =
nullptr;
679 MsgSendFpretFunctionDecl =
nullptr;
680 GetClassFunctionDecl =
nullptr;
681 GetMetaClassFunctionDecl =
nullptr;
682 GetSuperClassFunctionDecl =
nullptr;
683 SelGetUidFunctionDecl =
nullptr;
684 CFStringFunctionDecl =
nullptr;
685 ConstantStringClassReference =
nullptr;
686 NSStringRecord =
nullptr;
687 CurMethodDef =
nullptr;
688 CurFunctionDef =
nullptr;
689 GlobalVarDecl =
nullptr;
690 GlobalConstructionExp =
nullptr;
691 SuperStructDecl =
nullptr;
692 ProtocolTypeDecl =
nullptr;
693 ConstantStringDecl =
nullptr;
695 SuperConstructorFunctionDecl =
nullptr;
696 NumObjCStringLiterals = 0;
697 PropParentMap =
nullptr;
698 CurrentBody =
nullptr;
699 DisableReplaceStmt =
false;
700 objc_impl_method =
false;
703 MainFileID =
SM->getMainFileID();
704 llvm::MemoryBufferRef MainBuf =
SM->getBufferOrFake(MainFileID);
705 MainFileStart = MainBuf.getBufferStart();
706 MainFileEnd = MainBuf.getBufferEnd();
708 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
715void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *
D) {
726 if (
Loc.isInvalid())
return;
730 RewriteFunctionDecl(FD);
731 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(
D)) {
733 if (FVD->getName() ==
"_NSConstantStringClassReference") {
734 ConstantStringClassReference = FVD;
738 RewriteCategoryDecl(CD);
740 if (PD->isThisDeclarationADefinition())
741 RewriteProtocolDecl(PD);
745 DIEnd = LSD->decls_end();
748 if (!IFace->isThisDeclarationADefinition()) {
752 if (isa<ObjCInterfaceDecl>(*DI) &&
753 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
754 StartLoc == (*DI)->getBeginLoc())
760 }
while (DI != DIEnd);
761 RewriteForwardClassDecl(DG);
766 ObjCInterfacesSeen.push_back(IFace);
773 if (!Proto->isThisDeclarationADefinition()) {
777 if (isa<ObjCProtocolDecl>(*DI) &&
778 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
779 StartLoc == (*DI)->getBeginLoc())
785 }
while (DI != DIEnd);
786 RewriteForwardProtocolDecl(DG);
791 HandleTopLevelSingleDecl(*DI);
796 if (
SM->isWrittenInMainFile(
Loc))
797 return HandleDeclInMainFile(
D);
804void RewriteModernObjC::RewriteInclude() {
806 StringRef MainBuf =
SM->getBufferData(MainFileID);
807 const char *MainBufStart = MainBuf.begin();
808 const char *MainBufEnd = MainBuf.end();
809 size_t ImportLen = strlen(
"import");
812 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
813 if (*BufPtr ==
'#') {
814 if (++BufPtr == MainBufEnd)
816 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
817 if (++BufPtr == MainBufEnd)
819 if (!strncmp(BufPtr,
"import", ImportLen)) {
823 ReplaceText(ImportLoc, ImportLen,
"include");
832 Result +=
"OBJC_IVAR_$_";
843 std::string IvarOffsetName;
845 ObjCIvarBitfieldGroupOffset(
D, IvarOffsetName);
847 WriteInternalIvarName(ClassDecl,
D, IvarOffsetName);
849 std::string S =
"(*(";
852 IvarT = GetGroupRecordTypeForObjCIvarBitfield(
D);
859 auto *CDecl = cast<ObjCContainerDecl>(
D->getDeclContext());
862 CDecl = CatDecl->getClassInterface();
863 std::string RecName = std::string(CDecl->getName());
865 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
867 &Context->Idents.get(RecName));
868 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
869 unsigned UnsignedIntSize =
870 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
871 Expr *
Zero = IntegerLiteral::Create(*Context,
872 llvm::APInt(UnsignedIntSize, 0),
874 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
879 &Context->Idents.get(
D->getNameAsString()),
884 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
885 IvarT = Context->getDecltypeType(ME, ME->
getType());
888 convertObjCTypeToCStyleType(IvarT);
889 QualType castT = Context->getPointerType(IvarT);
890 std::string TypeString(castT.
getAsString(Context->getPrintingPolicy()));
895 S +=
"((char *)self + ";
898 if (
D->isBitField()) {
900 S +=
D->getNameAsString();
919 static bool objcGetPropertyDefined =
false;
920 static bool objcSetPropertyDefined =
false;
925 InsertText(startLoc,
"// ");
926 const char *startBuf =
SM->getCharacterData(startLoc);
927 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
928 const char *semiBuf = strchr(startBuf,
';');
929 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
940 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
943 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
944 bool GenGetProperty =
945 !(Attributes & ObjCPropertyAttribute::kind_nonatomic) &&
946 (Attributes & (ObjCPropertyAttribute::kind_retain |
947 ObjCPropertyAttribute::kind_copy));
949 if (GenGetProperty && !objcGetPropertyDefined) {
950 objcGetPropertyDefined =
true;
952 Getr =
"\nextern \"C\" __declspec(dllimport) "
953 "id objc_getProperty(id, SEL, long, bool);\n";
960 if (GenGetProperty) {
973 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
975 std::string ParamStr =
976 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
979 if (FT->isVariadic()) {
980 if (FT->getNumParams())
989 Getr +=
"return (_TYPE)";
990 Getr +=
"objc_getProperty(self, _cmd, ";
991 RewriteIvarOffsetComputation(OID, Getr);
995 Getr +=
"return " + getIvarAccessString(OID);
997 InsertText(startGetterSetterLoc, Getr);
1001 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1006 bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain |
1007 ObjCPropertyAttribute::kind_copy);
1008 if (GenSetProperty && !objcSetPropertyDefined) {
1009 objcSetPropertyDefined =
true;
1011 Setr =
"\nextern \"C\" __declspec(dllimport) "
1012 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1020 if (GenSetProperty) {
1021 Setr +=
"objc_setProperty (self, _cmd, ";
1022 RewriteIvarOffsetComputation(OID, Setr);
1026 if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
1030 if (Attributes & ObjCPropertyAttribute::kind_copy)
1036 Setr += getIvarAccessString(OID) +
" = ";
1040 InsertText(startGetterSetterLoc, Setr);
1044 std::string &typedefString) {
1045 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1047 typedefString +=
"\n";
1048 typedefString +=
"#define _REWRITER_typedef_";
1050 typedefString +=
"\n";
1051 typedefString +=
"typedef struct objc_object ";
1054 typedefString +=
";\ntypedef struct {} _objc_exc_";
1056 typedefString +=
";\n#endif\n";
1059void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1060 const std::string &typedefString) {
1062 const char *startBuf =
SM->getCharacterData(startLoc);
1063 const char *semiPtr = strchr(startBuf,
';');
1065 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1068void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1069 std::string typedefString;
1072 if (I ==
D.begin()) {
1076 typedefString +=
"// @class ";
1078 typedefString +=
";";
1080 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1083 HandleTopLevelSingleDecl(*I);
1086 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1089void RewriteModernObjC::RewriteForwardClassDecl(
1091 std::string typedefString;
1092 for (
unsigned i = 0; i <
D.size(); i++) {
1095 typedefString +=
"// @class ";
1097 typedefString +=
";";
1099 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1101 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(
D[0]), typedefString);
1104void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1112 if (
SM->getExpansionLineNumber(LocEnd) >
1113 SM->getExpansionLineNumber(LocStart)) {
1114 InsertText(LocStart,
"#if 0\n");
1115 ReplaceText(LocEnd, 1,
";\n#endif\n");
1117 InsertText(LocStart,
"// ");
1124 ReplaceText(
Loc, 0,
"// ");
1133 ReplaceText(LocStart, 1,
"/** ");
1137 ReplaceText(LocStart, 0,
"// ");
1144 RewriteMethodDeclaration(I);
1146 RewriteMethodDeclaration(I);
1150 strlen(
"@end"),
"/* @end */\n");
1158 ReplaceText(LocStart, 0,
"// ");
1161 RewriteMethodDeclaration(I);
1163 RewriteMethodDeclaration(I);
1169 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1172 const char *startBuf =
SM->getCharacterData(LocStart);
1173 const char *endBuf =
SM->getCharacterData(LocEnd);
1174 for (
const char *p = startBuf; p < endBuf; p++) {
1175 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1177 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1180 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1182 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1188void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1191 llvm_unreachable(
"Invalid SourceLocation");
1193 ReplaceText(LocStart, 0,
"// ");
1200 llvm_unreachable(
"Invalid SourceLocation");
1202 ReplaceText(LocStart, 0,
"// ");
1205void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1225 ResultStr +=
T.getAsString(Context->getPrintingPolicy());
1230 std::string &ResultStr) {
1233 ResultStr +=
"\nstatic ";
1234 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1238 std::string NameStr;
1256 int len = selString.size();
1257 for (
int i = 0; i < len; i++)
1258 if (selString[i] ==
':')
1260 NameStr += selString;
1263 MethodInternalNames[OMD] = NameStr;
1264 ResultStr += NameStr;
1271 QualType selfTy = Context->getObjCInterfaceType(IDecl);
1272 selfTy = Context->getPointerType(selfTy);
1273 if (!LangOpts.MicrosoftExt) {
1275 ResultStr +=
"struct ";
1282 ResultStr += Context->getObjCClassType().getAsString(
1283 Context->getPrintingPolicy());
1285 ResultStr +=
" self, ";
1286 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
1287 ResultStr +=
" _cmd";
1290 for (
const auto *PDecl : OMD->
parameters()) {
1292 if (PDecl->getType()->isObjCQualifiedIdType()) {
1299 (void)convertBlockPointerToFunctionPointer(QT);
1305 ResultStr +=
", ...";
1314 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1315 if (i) ResultStr +=
", ";
1316 std::string ParamStr =
1317 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
1318 ResultStr += ParamStr;
1320 if (FT->isVariadic()) {
1321 if (FT->getNumParams())
1332void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1335 assert((IMD || CID) &&
"Unknown implementation type");
1352 std::string ResultStr;
1357 const char *startBuf =
SM->getCharacterData(LocStart);
1358 const char *endBuf =
SM->getCharacterData(LocEnd);
1359 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1365 std::string ResultStr;
1370 const char *startBuf =
SM->getCharacterData(LocStart);
1371 const char *endBuf =
SM->getCharacterData(LocEnd);
1372 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1375 RewritePropertyImplDecl(I, IMD, CID);
1382 if (ObjCSynthesizedStructs.count(ClassDecl))
1386 while (SuperClass) {
1387 RewriteInterfaceDecl(SuperClass);
1390 std::string ResultStr;
1393 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1394 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1396 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1403 RewriteMethodDeclaration(I);
1405 RewriteMethodDeclaration(I);
1427 DisableReplaceStmtScope S(*
this);
1433 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1434 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1438 for (
unsigned i = 0; i < numArgs; i++) {
1440 if (isa<OpaqueValueExpr>(Arg))
1441 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1442 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1443 Args.push_back(Arg);
1453 case ObjCMessageExpr::Class:
1454 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1466 case ObjCMessageExpr::Instance:
1467 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1479 case ObjCMessageExpr::SuperClass:
1480 case ObjCMessageExpr::SuperInstance:
1481 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1496 Stmt *Replacement = SynthMessageExpr(NewMsg);
1497 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1514 DisableReplaceStmtScope S(*
this);
1518 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1519 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1522 for (
unsigned i = 0; i < numArgs; i++) {
1524 if (isa<OpaqueValueExpr>(Arg))
1525 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1526 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1527 Args.push_back(Arg);
1536 case ObjCMessageExpr::Class:
1537 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1549 case ObjCMessageExpr::Instance:
1550 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1562 case ObjCMessageExpr::SuperClass:
1563 case ObjCMessageExpr::SuperInstance:
1564 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1579 Stmt *Replacement = SynthMessageExpr(NewMsg);
1580 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1593void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1594 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1595 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1597 buf +=
"((id)l_collection,\n\t\t";
1598 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1600 buf +=
"&enumState, "
1601 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1608 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1614 buf =
"goto __break_label_";
1615 buf += utostr(ObjCBcLabelNo.back());
1616 ReplaceText(startLoc, strlen(
"break"), buf);
1621void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1623 std::string &LineString) {
1624 if (
Loc.isFileID() && GenerateLineInfo) {
1625 LineString +=
"\n#line ";
1627 LineString += utostr(PLoc.
getLine());
1628 LineString +=
" \"";
1629 LineString += Lexer::Stringify(PLoc.
getFilename());
1630 LineString +=
"\"\n";
1638 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1644 buf =
"goto __continue_label_";
1645 buf += utostr(ObjCBcLabelNo.back());
1646 ReplaceText(startLoc, strlen(
"continue"), buf);
1685 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1686 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1687 "ObjCForCollectionStmt Statement stack mismatch");
1688 assert(!ObjCBcLabelNo.empty() &&
1689 "ObjCForCollectionStmt - Label No stack empty");
1692 const char *startBuf =
SM->getCharacterData(startLoc);
1693 StringRef elementName;
1694 std::string elementTypeAsString;
1698 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1700 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1702 NamedDecl*
D = cast<NamedDecl>(DS->getSingleDecl());
1703 QualType ElementType = cast<ValueDecl>(
D)->getType();
1707 elementTypeAsString =
"id";
1709 elementTypeAsString = ElementType.
getAsString(Context->getPrintingPolicy());
1710 buf += elementTypeAsString;
1712 elementName =
D->getName();
1717 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1723 elementTypeAsString =
"id";
1729 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1731 buf +=
"id __rw_items[16];\n\t";
1733 buf +=
"id l_collection = (id)";
1735 const char *startCollectionBuf = startBuf;
1736 startCollectionBuf += 3;
1737 startCollectionBuf = strchr(startCollectionBuf,
'(');
1738 startCollectionBuf++;
1740 while (*startCollectionBuf !=
' ' ||
1741 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1742 (*(startCollectionBuf+3) !=
' ' &&
1743 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1744 startCollectionBuf++;
1745 startCollectionBuf += 3;
1748 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1751 const char *rparenBuf =
SM->getCharacterData(rightParenLoc);
1766 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1767 SynthCountByEnumWithState(buf);
1777 buf +=
"if (limit) {\n\t";
1778 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1779 buf +=
"do {\n\t\t";
1780 buf +=
"unsigned long counter = 0;\n\t\t";
1781 buf +=
"do {\n\t\t\t";
1782 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1783 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1786 buf += elementTypeAsString;
1787 buf +=
")enumState.itemsPtr[counter++];";
1789 ReplaceText(lparenLoc, 1, buf);
1803 buf +=
"__continue_label_";
1804 buf += utostr(ObjCBcLabelNo.back());
1807 buf +=
"} while (counter < limit);\n\t";
1808 buf +=
"} while ((limit = ";
1809 SynthCountByEnumWithState(buf);
1813 buf += elementTypeAsString;
1815 buf +=
"__break_label_";
1816 buf += utostr(ObjCBcLabelNo.back());
1819 buf +=
"else\n\t\t";
1822 buf += elementTypeAsString;
1828 if (isa<CompoundStmt>(S->getBody())) {
1830 InsertText(endBodyLoc, buf);
1839 const char *stmtBuf =
SM->getCharacterData(OrigEnd);
1840 const char *semiBuf = strchr(stmtBuf,
';');
1841 assert(semiBuf &&
"Can't find ';'");
1843 InsertText(endBodyLoc, buf);
1846 ObjCBcLabelNo.pop_back();
1850static void Write_RethrowObject(std::string &buf) {
1851 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1852 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1853 buf +=
"\tid rethrow;\n";
1854 buf +=
"\t} _fin_force_rethow(_rethrow);";
1866 const char *startBuf =
SM->getCharacterData(startLoc);
1868 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1872 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1873 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1875 const char *lparenBuf = startBuf;
1876 while (*lparenBuf !=
'(') lparenBuf++;
1877 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1879 buf =
"; objc_sync_enter(_sync_obj);\n";
1880 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1881 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1882 buf +=
"\n\tid sync_exit;";
1883 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1889 const char *RParenExprLocBuf =
SM->getCharacterData(RParenExprLoc);
1890 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1894 const char *LBraceLocBuf =
SM->getCharacterData(LBranceLoc);
1895 assert (*LBraceLocBuf ==
'{');
1896 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->getCharacterData(RParenExprLoc) + 1), buf);
1899 assert((*
SM->getCharacterData(startRBraceLoc) ==
'}') &&
1900 "bogus @synchronized block");
1902 buf =
"} catch (id e) {_rethrow = e;}\n";
1903 Write_RethrowObject(buf);
1907 ReplaceText(startRBraceLoc, 1, buf);
1912void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1915 for (
Stmt *SubStmt : S->children())
1917 WarnAboutReturnGotoStmts(SubStmt);
1919 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1920 Diags.
Report(Context->getFullLoc(S->getBeginLoc()),
1921 TryFinallyContainsReturnDiag);
1927 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1928 ReplaceText(S->getSubStmt()->getBeginLoc(), 1,
1929 "{ __AtAutoreleasePool __autoreleasepool; ");
1936 bool noCatch = S->getNumCatchStmts() == 0;
1939 ConvertSourceLocationToLineDirective(TryLocation, buf);
1943 buf +=
"{ id volatile _rethrow = 0;\n";
1945 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1950 const char *startBuf =
SM->getCharacterData(startLoc);
1952 assert((*startBuf ==
'@') &&
"bogus @try location");
1954 ReplaceText(startLoc, 1, buf);
1957 ReplaceText(startLoc, 1,
"");
1960 VarDecl *catchDecl = Catch->getCatchParamDecl();
1962 startLoc = Catch->getBeginLoc();
1963 bool AtRemoved =
false;
1972 ConvertSourceLocationToLineDirective(Catch->getBeginLoc(), Result);
1974 startBuf =
SM->getCharacterData(startLoc);
1975 assert((*startBuf ==
'@') &&
"bogus @catch location");
1977 const char *rParenBuf =
SM->getCharacterData(rParenLoc);
1983 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1994 ReplaceText(lBraceLoc, 1, Result);
2001 ReplaceText(startLoc, 1,
"");
2009 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2010 buf +=
"catch (id e) {_rethrow = e;}\n";
2014 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2015 buf +=
"catch (id e) {_rethrow = e;}\n";
2019 ReplaceText(startFinalLoc, 8, buf);
2023 Write_RethrowObject(buf);
2024 ReplaceText(startFinalBodyLoc, 1, buf);
2027 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2029 WarnAboutReturnGotoStmts(S->getTryBody());
2041 const char *startBuf =
SM->getCharacterData(startLoc);
2043 assert((*startBuf ==
'@') &&
"bogus @throw location");
2047 if (S->getThrowExpr())
2048 buf =
"objc_exception_throw(";
2053 const char *wBuf = strchr(startBuf,
'w');
2054 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2055 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2058 const char *endBuf =
SM->getCharacterData(endLoc);
2059 const char *semiBuf = strchr(endBuf,
';');
2060 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2062 if (S->getThrowExpr())
2063 ReplaceText(semiLoc, 1,
");");
2069 std::string StrEncoding;
2070 Context->getObjCEncodingForType(Exp->
getEncodedType(), StrEncoding);
2071 Expr *Replacement = getStringLiteral(StrEncoding);
2072 ReplaceStmt(Exp, Replacement);
2080 if (!SelGetUidFunctionDecl)
2081 SynthSelGetUidFunctionDecl();
2082 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2086 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2088 ReplaceStmt(Exp, SelExp);
2094RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2106 QualType pToFunc = Context->getPointerType(msgSendType);
2108 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
2113 CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
2118static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2119 const char *&startRef,
const char *&endRef) {
2120 while (startBuf < endBuf) {
2121 if (*startBuf ==
'<')
2122 startRef = startBuf;
2123 if (*startBuf ==
'>') {
2124 if (startRef && *startRef ==
'<') {
2135static void scanToNextArgument(
const char *&argRef) {
2137 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2140 else if (*argRef ==
'>')
2144 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2147bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2159 QualType ElemTy = Context->getBaseElementType(T);
2160 return needToScanForQualifiers(ElemTy);
2165void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *
E) {
2167 if (needToScanForQualifiers(
Type)) {
2171 Loc = ECE->getLParenLoc();
2172 EndLoc = ECE->getRParenLoc();
2174 Loc =
E->getBeginLoc();
2175 EndLoc =
E->getEndLoc();
2181 const char *startBuf =
SM->getCharacterData(
Loc);
2182 const char *endBuf =
SM->getCharacterData(EndLoc);
2183 const char *startRef =
nullptr, *endRef =
nullptr;
2184 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2189 InsertText(LessLoc,
"/*");
2190 InsertText(GreaterLoc,
"*/");
2195void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2199 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2203 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2208 assert(funcType &&
"missing function type");
2209 proto = dyn_cast<FunctionProtoType>(funcType);
2214 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2219 Loc = TD->getLocation();
2220 Type = TD->getUnderlyingType();
2225 if (needToScanForQualifiers(
Type)) {
2228 const char *endBuf =
SM->getCharacterData(
Loc);
2229 const char *startBuf = endBuf;
2230 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2232 const char *startRef =
nullptr, *endRef =
nullptr;
2233 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2238 InsertText(LessLoc,
"/*");
2239 InsertText(GreaterLoc,
"*/");
2245 const char *startBuf =
SM->getCharacterData(
Loc);
2246 const char *startFuncBuf = startBuf;
2251 const char *endBuf = startBuf;
2253 scanToNextArgument(endBuf);
2254 const char *startRef =
nullptr, *endRef =
nullptr;
2255 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2258 Loc.getLocWithOffset(startRef-startFuncBuf);
2260 Loc.getLocWithOffset(endRef-startFuncBuf+1);
2262 InsertText(LessLoc,
"/*");
2263 InsertText(GreaterLoc,
"*/");
2265 startBuf = ++endBuf;
2270 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2277void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2280 if (!isa<TypeOfExprType>(TypePtr))
2282 while (isa<TypeOfExprType>(TypePtr)) {
2283 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2289 std::string TypeAsString(QT.
getAsString(Context->getPrintingPolicy()));
2291 const char *startBuf =
SM->getCharacterData(DeclLoc);
2294 TypeAsString +=
" " + Name +
" = ";
2298 startLoc = ECE->getLParenLoc();
2300 startLoc =
E->getBeginLoc();
2301 startLoc =
SM->getExpansionLoc(startLoc);
2302 const char *endBuf =
SM->getCharacterData(startLoc);
2303 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2307 X =
SM->getExpansionLoc(
X);
2308 const char *endBuf =
SM->getCharacterData(
X);
2309 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2314void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2315 IdentifierInfo *SelGetUidIdent = &Context->Idents.get(
"sel_registerName");
2317 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2319 getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
2320 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2323 SelGetUidIdent, getFuncType,
2324 nullptr, SC_Extern);
2327void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2330 FD->
getName() ==
"sel_registerName") {
2331 SelGetUidFunctionDecl = FD;
2334 RewriteObjCQualifiedInterfaceTypes(FD);
2337void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2338 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2339 const char *argPtr = TypeString.c_str();
2340 if (!strchr(argPtr,
'^')) {
2345 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2351void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2354 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2355 const char *argPtr = TypeString.c_str();
2380void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2387 std::string FdStr =
Type.getAsString(Context->getPrintingPolicy());
2391 unsigned numArgs = proto->getNumParams();
2392 for (
unsigned i = 0; i < numArgs; i++) {
2393 QualType ArgType = proto->getParamType(i);
2394 RewriteBlockPointerType(FdStr, ArgType);
2399 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2403 InsertText(FunLocStart, FdStr);
2407void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2408 if (SuperConstructorFunctionDecl)
2410 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"__rw_objc_super");
2412 QualType argT = Context->getObjCIdType();
2413 assert(!argT.
isNull() &&
"Can't find 'id' type");
2414 ArgTys.push_back(argT);
2415 ArgTys.push_back(argT);
2416 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2418 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2421 msgSendIdent, msgSendType,
2422 nullptr, SC_Extern);
2426void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2427 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend");
2429 QualType argT = Context->getObjCIdType();
2430 assert(!argT.
isNull() &&
"Can't find 'id' type");
2431 ArgTys.push_back(argT);
2432 argT = Context->getObjCSelType();
2433 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2434 ArgTys.push_back(argT);
2435 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2437 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2440 msgSendIdent, msgSendType,
nullptr,
2445void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2446 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSendSuper");
2448 ArgTys.push_back(Context->VoidTy);
2449 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2451 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2454 msgSendIdent, msgSendType,
2455 nullptr, SC_Extern);
2459void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2460 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_stret");
2462 QualType argT = Context->getObjCIdType();
2463 assert(!argT.
isNull() &&
"Can't find 'id' type");
2464 ArgTys.push_back(argT);
2465 argT = Context->getObjCSelType();
2466 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2467 ArgTys.push_back(argT);
2468 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2470 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2473 msgSendIdent, msgSendType,
2474 nullptr, SC_Extern);
2479void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2481 &Context->Idents.get(
"objc_msgSendSuper_stret");
2483 ArgTys.push_back(Context->VoidTy);
2484 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2486 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2490 msgSendType,
nullptr,
2495void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2496 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_fpret");
2498 QualType argT = Context->getObjCIdType();
2499 assert(!argT.
isNull() &&
"Can't find 'id' type");
2500 ArgTys.push_back(argT);
2501 argT = Context->getObjCSelType();
2502 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2503 ArgTys.push_back(argT);
2504 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
2506 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2509 msgSendIdent, msgSendType,
2510 nullptr, SC_Extern);
2514void RewriteModernObjC::SynthGetClassFunctionDecl() {
2515 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getClass");
2517 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2518 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2520 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2523 getClassIdent, getClassType,
2524 nullptr, SC_Extern);
2528void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2530 &Context->Idents.get(
"class_getSuperclass");
2532 ArgTys.push_back(Context->getObjCClassType());
2533 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2535 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2539 getClassType,
nullptr,
2544void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2545 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getMetaClass");
2547 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2548 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2550 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2553 getClassIdent, getClassType,
2554 nullptr, SC_Extern);
2558 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2559 QualType strType = getConstantStringStructType();
2561 std::string S =
"__NSConstantStringImpl_";
2563 std::string tmpName = InFileName;
2565 for (i=0; i < tmpName.length(); i++) {
2566 char c = tmpName.at(i);
2573 S += utostr(NumObjCStringLiterals++);
2575 Preamble +=
"static __NSConstantStringImpl " + S;
2576 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2579 std::string prettyBufS;
2580 llvm::raw_string_ostream prettyBuf(prettyBufS);
2588 strType,
nullptr, SC_Static);
2591 Expr *Unop = UnaryOperator::Create(
2592 const_cast<ASTContext &
>(*Context), DRE, UO_AddrOf,
2593 Context->getPointerType(DRE->
getType()), VK_PRValue, OK_Ordinary,
2597 CK_CPointerToObjCPointerCast, Unop);
2598 ReplaceStmt(Exp, cast);
2605 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
2607 Expr *FlagExp = IntegerLiteral::Create(*Context,
2608 llvm::APInt(IntSize, Exp->
getValue()),
2610 CastExpr *
cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
2611 CK_BitCast, FlagExp);
2614 ReplaceStmt(Exp, PE);
2620 if (!SelGetUidFunctionDecl)
2621 SynthSelGetUidFunctionDecl();
2623 if (!MsgSendFunctionDecl)
2624 SynthMsgSendFunctionDecl();
2625 if (!GetClassFunctionDecl)
2626 SynthGetClassFunctionDecl();
2641 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2642 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2644 MsgExprs.push_back(Cls);
2651 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2652 SelExprs, StartLoc, EndLoc);
2653 MsgExprs.push_back(SelExp);
2662 CK = CK_IntegralToBoolean;
2663 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2665 MsgExprs.push_back(subExpr);
2668 ArgTypes.push_back(Context->getObjCClassType());
2669 ArgTypes.push_back(Context->getObjCSelType());
2670 for (
const auto PI : BoxingMethod->
parameters())
2671 ArgTypes.push_back(PI->getType());
2679 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2682 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2686 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2687 castType = Context->getPointerType(castType);
2688 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2695 CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
2697 ReplaceStmt(Exp, CE);
2703 if (!SelGetUidFunctionDecl)
2704 SynthSelGetUidFunctionDecl();
2706 if (!MsgSendFunctionDecl)
2707 SynthMsgSendFunctionDecl();
2708 if (!GetClassFunctionDecl)
2709 SynthGetClassFunctionDecl();
2718 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2719 std::string NSArrayFName(
"__NSContainer_literal");
2720 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2722 *Context, NSArrayFD,
false, NSArrayFType, VK_PRValue,
SourceLocation());
2726 unsigned UnsignedIntSize =
2727 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2728 Expr *count = IntegerLiteral::Create(*Context,
2729 llvm::APInt(UnsignedIntSize, NumElements),
2731 InitExprs.push_back(count);
2732 for (
unsigned i = 0; i < NumElements; i++)
2734 Expr *NSArrayCallExpr =
2735 CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue,
2740 &Context->Idents.get(
"arr"),
2741 Context->getPointerType(Context->VoidPtrTy),
2745 MemberExpr::CreateImplicit(*Context, NSArrayCallExpr,
false, ARRFD,
2746 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2747 QualType ConstIdT = Context->getObjCIdType().withConst();
2749 NoTypeInfoCStyleCastExpr(Context,
2750 Context->getPointerType(ConstIdT),
2764 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2765 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2767 MsgExprs.push_back(Cls);
2775 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2776 SelExprs, StartLoc, EndLoc);
2777 MsgExprs.push_back(SelExp);
2780 MsgExprs.push_back(ArrayLiteralObjects);
2783 Expr *cnt = IntegerLiteral::Create(*Context,
2784 llvm::APInt(UnsignedIntSize, NumElements),
2786 MsgExprs.push_back(cnt);
2789 ArgTypes.push_back(Context->getObjCClassType());
2790 ArgTypes.push_back(Context->getObjCSelType());
2791 for (
const auto *PI : ArrayMethod->
parameters())
2792 ArgTypes.push_back(PI->getType());
2800 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2803 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2807 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2808 castType = Context->getPointerType(castType);
2809 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2818 ReplaceStmt(Exp, CE);
2824 if (!SelGetUidFunctionDecl)
2825 SynthSelGetUidFunctionDecl();
2827 if (!MsgSendFunctionDecl)
2828 SynthMsgSendFunctionDecl();
2829 if (!GetClassFunctionDecl)
2830 SynthGetClassFunctionDecl();
2839 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2840 std::string NSDictFName(
"__NSContainer_literal");
2841 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2843 *Context, NSDictFD,
false, NSDictFType, VK_PRValue,
SourceLocation());
2849 unsigned UnsignedIntSize =
2850 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2851 Expr *count = IntegerLiteral::Create(*Context,
2852 llvm::APInt(UnsignedIntSize, NumElements),
2854 KeyExprs.push_back(count);
2855 ValueExprs.push_back(count);
2856 for (
unsigned i = 0; i < NumElements; i++) {
2858 KeyExprs.push_back(Element.Key);
2859 ValueExprs.push_back(Element.Value);
2863 Expr *NSValueCallExpr =
2864 CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue,
2869 &Context->Idents.get(
"arr"),
2870 Context->getPointerType(Context->VoidPtrTy),
2874 MemberExpr::CreateImplicit(*Context, NSValueCallExpr,
false, ARRFD,
2875 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2876 QualType ConstIdT = Context->getObjCIdType().withConst();
2878 NoTypeInfoCStyleCastExpr(Context,
2879 Context->getPointerType(ConstIdT),
2881 DictLiteralValueME);
2883 Expr *NSKeyCallExpr =
2884 CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue,
2888 MemberExpr::CreateImplicit(*Context, NSKeyCallExpr,
false, ARRFD,
2889 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2892 NoTypeInfoCStyleCastExpr(Context,
2893 Context->getPointerType(ConstIdT),
2907 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2908 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2910 MsgExprs.push_back(Cls);
2917 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2918 SelExprs, StartLoc, EndLoc);
2919 MsgExprs.push_back(SelExp);
2922 MsgExprs.push_back(DictValueObjects);
2925 MsgExprs.push_back(DictKeyObjects);
2928 Expr *cnt = IntegerLiteral::Create(*Context,
2929 llvm::APInt(UnsignedIntSize, NumElements),
2931 MsgExprs.push_back(cnt);
2934 ArgTypes.push_back(Context->getObjCClassType());
2935 ArgTypes.push_back(Context->getObjCSelType());
2936 for (
const auto *PI : DictMethod->
parameters()) {
2940 convertToUnqualifiedObjCType(PointeeTy);
2941 T = Context->getPointerType(PointeeTy);
2943 ArgTypes.push_back(T);
2952 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2955 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2959 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2960 castType = Context->getPointerType(castType);
2961 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2970 ReplaceStmt(Exp, CE);
2977QualType RewriteModernObjC::getSuperStructType() {
2978 if (!SuperStructDecl) {
2979 SuperStructDecl = RecordDecl::Create(
2985 FieldTypes[0] = Context->getObjCIdType();
2987 FieldTypes[1] = Context->getObjCIdType();
2990 for (
unsigned i = 0; i < 2; ++i) {
2991 SuperStructDecl->
addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2994 FieldTypes[i],
nullptr,
3002 return Context->getTagDeclType(SuperStructDecl);
3005QualType RewriteModernObjC::getConstantStringStructType() {
3006 if (!ConstantStringDecl) {
3007 ConstantStringDecl = RecordDecl::Create(
3009 SourceLocation(), &Context->Idents.get(
"__NSConstantStringImpl"));
3013 FieldTypes[0] = Context->getObjCIdType();
3015 FieldTypes[1] = Context->IntTy;
3017 FieldTypes[2] = Context->getPointerType(Context->CharTy);
3019 FieldTypes[3] = Context->LongTy;
3022 for (
unsigned i = 0; i < 4; ++i) {
3023 ConstantStringDecl->
addDecl(FieldDecl::Create(*Context,
3027 FieldTypes[i],
nullptr,
3035 return Context->getTagDeclType(ConstantStringDecl);
3041static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3047 if (!LSD->getRBraceLoc().isValid())
3048 return LSD->getExternLoc();
3051 R.RewriteBlockLiteralFunctionDecl(FD);
3055void RewriteModernObjC::RewriteLineDirective(
const Decl *
D) {
3059 if (Location.
isFileID() && GenerateLineInfo) {
3060 std::string LineString(
"\n#line ");
3062 LineString += utostr(PLoc.
getLine());
3063 LineString +=
" \"";
3064 LineString += Lexer::Stringify(PLoc.
getFilename());
3065 if (isa<ObjCMethodDecl>(
D))
3067 else LineString +=
"\"\n";
3069 Location =
D->getBeginLoc();
3075 if (!LSD->getRBraceLoc().isValid())
3076 Location = LSD->getExternLoc();
3079 InsertText(Location, LineString);
3093Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3099 QualType FuncType = getSimpleFunctionType(
3100 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3101 QualType castType = Context->getPointerType(FuncType);
3104 static unsigned stretCount=0;
3105 std::string
name =
"__Stret";
name += utostr(stretCount);
3107 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3108 str +=
"namespace {\n";
3109 str +=
"struct "; str +=
name;
3112 str +=
"(id receiver, SEL sel";
3113 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3114 std::string ArgName =
"arg"; ArgName += utostr(i);
3115 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
3116 str +=
", "; str += ArgName;
3119 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3120 std::string ArgName =
"arg"; ArgName += utostr(i);
3121 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3122 Context->getPrintingPolicy());
3123 str +=
", "; str += ArgName;
3127 str +=
"\t unsigned size = sizeof(";
3128 str += returnType.
getAsString(Context->getPrintingPolicy()); str +=
");\n";
3130 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3132 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3133 str +=
")(void *)objc_msgSend)(receiver, sel";
3134 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3135 str +=
", arg"; str += utostr(i);
3138 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3139 str +=
", arg"; str += utostr(i);
3143 str +=
"\t else if (receiver == 0)\n";
3144 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3147 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3148 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3149 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3150 str +=
", arg"; str += utostr(i);
3153 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3154 str +=
", arg"; str += utostr(i);
3159 str +=
"\t"; str += returnType.
getAsString(Context->getPrintingPolicy());
3161 str +=
"};\n};\n\n";
3164 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3166 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3170 InsertText(FunLocStart, str);
3177 ID, FuncType,
nullptr, SC_Extern,
false,
false);
3181 CallExpr::Create(*Context, DRE, MsgExprs, castType, VK_LValue,
3186 &Context->Idents.get(
"s"),
3187 returnType,
nullptr,
3191 *Context, STCE,
false, FieldD, FieldD->
getType(), VK_LValue, OK_Ordinary);
3199 if (!SelGetUidFunctionDecl)
3200 SynthSelGetUidFunctionDecl();
3201 if (!MsgSendFunctionDecl)
3202 SynthMsgSendFunctionDecl();
3203 if (!MsgSendSuperFunctionDecl)
3204 SynthMsgSendSuperFunctionDecl();
3205 if (!MsgSendStretFunctionDecl)
3206 SynthMsgSendStretFunctionDecl();
3207 if (!MsgSendSuperStretFunctionDecl)
3208 SynthMsgSendSuperStretFunctionDecl();
3209 if (!MsgSendFpretFunctionDecl)
3210 SynthMsgSendFpretFunctionDecl();
3211 if (!GetClassFunctionDecl)
3212 SynthGetClassFunctionDecl();
3213 if (!GetSuperClassFunctionDecl)
3214 SynthGetSuperClassFunctionDecl();
3215 if (!GetMetaClassFunctionDecl)
3216 SynthGetMetaClassFunctionDecl();
3223 QualType resultType = mDecl->getReturnType();
3225 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3227 MsgSendFlavor = MsgSendFpretFunctionDecl;
3233 case ObjCMessageExpr::SuperClass: {
3234 MsgSendFlavor = MsgSendSuperFunctionDecl;
3235 if (MsgSendStretFlavor)
3236 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3237 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3244 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3245 Context, Context->getObjCIdType(), CK_BitCast,
3247 Context->getObjCIdType(), VK_PRValue,
3254 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3255 ClsExprs, StartLoc, EndLoc);
3257 ClsExprs.push_back(Cls);
3258 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3263 InitExprs.push_back(
3264 NoTypeInfoCStyleCastExpr(Context,
3265 Context->getObjCIdType(),
3268 QualType superType = getSuperStructType();
3271 if (LangOpts.MicrosoftExt) {
3272 SynthSuperConstructorFunctionDecl();
3275 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3278 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3286 SuperRep = UnaryOperator::Create(
3287 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3288 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3290 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3291 Context->getPointerType(superType),
3292 CK_BitCast, SuperRep);
3299 = Context->getTrivialTypeSourceInfo(superType);
3304 SuperRep = UnaryOperator::Create(
3305 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3306 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3309 MsgExprs.push_back(SuperRep);
3313 case ObjCMessageExpr::Class: {
3318 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3319 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3321 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3322 Context->getObjCIdType(),
3324 MsgExprs.push_back(ArgExpr);
3328 case ObjCMessageExpr::SuperInstance:{
3329 MsgSendFlavor = MsgSendSuperFunctionDecl;
3330 if (MsgSendStretFlavor)
3331 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3332 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3336 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3337 Context, Context->getObjCIdType(), CK_BitCast,
3339 Context->getObjCIdType(), VK_PRValue,
3346 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3349 ClsExprs.push_back(Cls);
3350 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3355 InitExprs.push_back(
3357 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3360 QualType superType = getSuperStructType();
3363 if (LangOpts.MicrosoftExt) {
3364 SynthSuperConstructorFunctionDecl();
3367 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3370 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3378 SuperRep = UnaryOperator::Create(
3379 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3380 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3382 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3383 Context->getPointerType(superType),
3384 CK_BitCast, SuperRep);
3391 = Context->getTrivialTypeSourceInfo(superType);
3395 MsgExprs.push_back(SuperRep);
3399 case ObjCMessageExpr::Instance: {
3404 recExpr = CE->getSubExpr();
3407 ? CK_BlockPointerToObjCPointerCast
3408 : CK_CPointerToObjCPointerCast;
3410 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3412 MsgExprs.push_back(recExpr);
3420 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3421 SelExprs, StartLoc, EndLoc);
3422 MsgExprs.push_back(SelExp);
3425 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3431 if (needToScanForQualifiers(type))
3432 type = Context->getObjCIdType();
3434 (void)convertBlockPointerToFunctionPointer(type);
3438 type->isBooleanType()) {
3439 CK = CK_IntegralToBoolean;
3440 }
else if (
type->isObjCObjectPointerType()) {
3442 CK = CK_BlockPointerToObjCPointerCast;
3444 CK = CK_CPointerToObjCPointerCast;
3452 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3455 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3456 if (CE->getType()->isObjCQualifiedIdType()) {
3457 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3458 userExpr = CE->getSubExpr();
3461 CK = CK_IntegralToPointer;
3463 CK = CK_BlockPointerToObjCPointerCast;
3465 CK = CK_CPointerToObjCPointerCast;
3469 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3473 MsgExprs.push_back(userExpr);
3485 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3486 ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
3488 ArgTypes.push_back(Context->getObjCIdType());
3489 ArgTypes.push_back(Context->getObjCSelType());
3494 ? Context->getObjCIdType()
3497 (void)convertBlockPointerToFunctionPointer(t);
3498 ArgTypes.push_back(t);
3501 convertToUnqualifiedObjCType(returnType);
3502 (void)convertBlockPointerToFunctionPointer(returnType);
3504 returnType = Context->getObjCIdType();
3511 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
3517 cast = NoTypeInfoCStyleCastExpr(Context,
3518 Context->getPointerType(Context->VoidTy),
3525 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->
isVariadic() :
true);
3526 castType = Context->getPointerType(castType);
3527 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3536 Stmt *ReplacingStmt = CE;
3537 if (MsgSendStretFlavor) {
3543 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3547 ReplacingStmt = STCE;
3550 return ReplacingStmt;
3554 Stmt *ReplacingStmt =
3558 ReplaceStmt(Exp, ReplacingStmt);
3561 return ReplacingStmt;
3565QualType RewriteModernObjC::getProtocolType() {
3566 if (!ProtocolTypeDecl) {
3568 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3569 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3571 &Context->Idents.get(
"Protocol"),
3574 return Context->getTypeDeclType(ProtocolTypeDecl);
3582 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3587 nullptr, SC_Extern);
3591 Context, Context->getPointerType(DRE->
getType()), CK_BitCast, DRE);
3592 ReplaceStmt(Exp, castExpr);
3602 bool &IsNamedDefinition) {
3606 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3610 IsNamedDefinition =
true;
3612 return Context->getSourceManager().isBeforeInTranslationUnit(
3615 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3616 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3618 IsNamedDefinition =
true;
3619 TagLocation = ED->getLocation();
3620 return Context->getSourceManager().isBeforeInTranslationUnit(
3628bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &
Type,
3629 std::string &Result) {
3637 return RewriteObjCFieldDeclType(ElemTy, Result);
3643 Result +=
"\n\tstruct ";
3645 Result +=
"\n\tunion ";
3647 assert(
false &&
"class not allowed as an ivar type");
3650 if (GlobalDefinedTags.count(RD)) {
3656 for (
auto *FD : RD->
fields())
3657 RewriteObjCFieldDecl(FD, Result);
3665 Result +=
"\n\tenum ";
3667 if (GlobalDefinedTags.count(ED)) {
3675 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3676 Result +=
toString(EC->getInitVal(), 10);
3685 convertObjCTypeToCStyleType(
Type);
3692void RewriteModernObjC::RewriteObjCFieldDecl(
FieldDecl *fieldDecl,
3693 std::string &Result) {
3695 std::string Name =
fieldDecl->getNameAsString();
3697 bool EleboratedType = RewriteObjCFieldDeclType(
Type, Result);
3698 if (!EleboratedType)
3699 Type.getAsStringInternal(Name, Context->getPrintingPolicy());
3702 Result +=
" : "; Result += utostr(
fieldDecl->getBitWidthValue(*Context));
3709 llvm::APInt
Dim = CAT->getSize();
3710 Result += utostr(
Dim.getZExtValue());
3722void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3723 std::string &Result) {
3728 Type = Context->getBaseElementType(
Type);
3730 auto *IDecl = dyn_cast<ObjCContainerDecl>(
fieldDecl->getDeclContext());
3741 if (GlobalDefinedTags.count(TD))
3744 bool IsNamedDefinition =
false;
3745 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3746 RewriteObjCFieldDeclType(
Type, Result);
3749 if (IsNamedDefinition)
3750 GlobalDefinedTags.insert(TD);
3754unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3756 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3757 return IvarGroupNumber[IV];
3759 unsigned GroupNo = 0;
3763 IVars.push_back(IVD);
3765 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3766 if (IVars[i]->isBitField()) {
3767 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3768 while (i < e && IVars[i]->isBitField())
3769 IvarGroupNumber[IVars[i++]] = GroupNo;
3774 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3775 return IvarGroupNumber[IV];
3778QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3781 std::string StructTagName;
3782 ObjCIvarBitfieldGroupType(IV, StructTagName);
3784 *Context, TagTypeKind::Struct, Context->getTranslationUnitDecl(),
3786 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3789 &Context->Idents.get(Ivar->
getName()),
3792 false, ICIS_NoInit));
3795 return Context->getTagDeclType(RD);
3800 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3801 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3802 if (GroupRecordType.count(tuple))
3803 return GroupRecordType[tuple];
3808 if (IVD->isBitField())
3811 if (!IVars.empty()) {
3812 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3814 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3815 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3820 if (!IVars.empty()) {
3822 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3823 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3824 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3826 QualType RetQT = GroupRecordType[tuple];
3827 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3834void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3835 std::string &Result) {
3838 Result +=
"__GRBF_";
3839 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3840 Result += utostr(GroupNo);
3846void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3847 std::string &Result) {
3851 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3852 Result += utostr(GroupNo);
3858void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3859 std::string &Result) {
3860 Result +=
"OBJC_IVAR_$_";
3861 ObjCIvarBitfieldGroupDecl(IV, Result);
3864#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3865 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3874 std::string &Result) {
3875 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3876 assert(CDecl->
getName() !=
"" &&
3877 "Name missing in SynthesizeObjCInternalStruct");
3882 IVars.push_back(IVD);
3887 const char *startBuf =
SM->getCharacterData(LocStart);
3888 const char *endBuf =
SM->getCharacterData(LocEnd);
3893 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3894 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3895 ReplaceText(LocStart, endBuf-startBuf, Result);
3902 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3903 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3907 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3908 if (IVars[i]->isBitField()) {
3910 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3911 RewriteObjCFieldDeclType(QT, Result);
3914 SKIP_BITFIELDS(i , e, IVars);
3917 Result +=
"\nstruct ";
3919 Result +=
"_IMPL {\n";
3921 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3924 Result +=
"_IVARS;\n";
3927 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3928 if (IVars[i]->isBitField()) {
3930 Result +=
"\tstruct ";
3931 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3932 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3934 SKIP_BITFIELDS(i , e, IVars);
3937 RewriteObjCFieldDecl(IVars[i], Result);
3941 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3942 ReplaceText(LocStart, endBuf-startBuf, Result);
3944 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3945 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3951 std::string &Result) {
3959 llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
3962 unsigned GroupNo = 0;
3964 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3965 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3969 if (LangOpts.MicrosoftExt)
3970 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3971 Result +=
"extern \"C\" ";
3972 if (LangOpts.MicrosoftExt &&
3975 Result +=
"__declspec(dllimport) ";
3977 Result +=
"unsigned long ";
3979 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3980 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3983 WriteInternalIvarName(CDecl, IvarDecl, Result);
3995void RewriteModernObjC::RewriteImplementations() {
3996 int ClsDefCount = ClassImplementation.size();
3997 int CatDefCount = CategoryImplementation.size();
4000 for (
int i = 0; i < ClsDefCount; i++) {
4005 "Legacy implicit interface rewriting not supported in moder abi");
4006 RewriteImplementationDecl(OIMP);
4009 for (
int i = 0; i < CatDefCount; i++) {
4014 "Legacy implicit interface rewriting not supported in moder abi");
4015 RewriteImplementationDecl(CIMP);
4019void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4020 const std::string &Name,
4022 assert(BlockByRefDeclNo.count(VD) &&
4023 "RewriteByRefString: ByRef decl missing");
4025 ResultStr +=
"struct ";
4026 ResultStr +=
"__Block_byref_" + Name +
4027 "_" + utostr(BlockByRefDeclNo[VD]) ;
4030static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4031 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4032 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4036std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4038 const std::string &Tag) {
4041 std::string StructRef =
"struct " +
Tag;
4044 ConvertSourceLocationToLineDirective(BlockLoc, S);
4046 S +=
"static " + RT.
getAsString(Context->getPrintingPolicy()) +
" __" +
4047 funcName.str() +
"_block_func_" + utostr(i);
4051 if (isa<FunctionNoProtoType>(AFT)) {
4054 S +=
"(" + StructRef +
" *__cself)";
4056 S +=
"(" + StructRef +
" *__cself)";
4059 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4062 S += StructRef +
" *__cself, ";
4063 std::string ParamStr;
4067 ParamStr = (*AI)->getNameAsString();
4069 (void)convertBlockPointerToFunctionPointer(QT);
4086 std::string TypeString;
4087 RewriteByRefString(TypeString, Name, VD);
4089 Name = TypeString + Name;
4090 S += Name +
" = __cself->" + VD->
getNameAsString() +
"; // bound by ref\n";
4093 for (
ValueDecl *VD : BlockByCopyDecls) {
4105 if (isTopLevelBlockPointerType(VD->
getType())) {
4106 RewriteBlockPointerTypeVariable(S, VD);
4108 RewriteBlockPointerType(S, VD->
getType());
4114 if (HasLocalVariableExternalStorage(VD))
4115 QT = Context->getPointerType(QT);
4118 "; // bound by copy\n";
4121 std::string RewrittenStr = RewrittenBlockExprs[CE];
4122 const char *cstr = RewrittenStr.c_str();
4123 while (*cstr++ !=
'{') ;
4129std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
4130 BlockExpr *CE,
int i, StringRef funcName,
const std::string &Tag) {
4131 std::string StructRef =
"struct " +
Tag;
4132 std::string S =
"static void __";
4135 S +=
"_block_copy_" + utostr(i);
4136 S +=
"(" + StructRef;
4137 S +=
"*dst, " + StructRef;
4139 for (
ValueDecl *VD : ImportedBlockDecls) {
4140 S +=
"_Block_object_assign((void*)&dst->";
4142 S +=
", (void*)src->";
4144 if (BlockByRefDecls.count(VD))
4145 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4147 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4149 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4153 S +=
"\nstatic void __";
4155 S +=
"_block_dispose_" + utostr(i);
4156 S +=
"(" + StructRef;
4158 for (
ValueDecl *VD : ImportedBlockDecls) {
4159 S +=
"_Block_object_dispose((void*)src->";
4161 if (BlockByRefDecls.count(VD))
4162 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4164 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4166 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4172std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE,
4173 const std::string &Tag,
4174 const std::string &Desc) {
4175 std::string S =
"\nstruct " +
Tag;
4178 S +=
" {\n struct __block_impl impl;\n";
4179 S +=
" struct " + Desc;
4186 if (BlockDeclRefs.size()) {
4188 for (
ValueDecl *VD : BlockByCopyDecls) {
4191 std::string ArgName =
"_" + FieldName;
4202 if (isTopLevelBlockPointerType(VD->
getType())) {
4203 S +=
"struct __block_impl *";
4207 if (HasLocalVariableExternalStorage(VD))
4208 QT = Context->getPointerType(QT);
4213 S += FieldName +
";\n";
4219 std::string ArgName =
"_" + FieldName;
4221 std::string TypeString;
4222 RewriteByRefString(TypeString, FieldName, VD);
4224 FieldName = TypeString + FieldName;
4225 ArgName = TypeString + ArgName;
4228 S += FieldName +
"; // by ref\n";
4233 bool firsTime =
true;
4234 for (
const ValueDecl *VD : BlockByCopyDecls) {
4241 if (isTopLevelBlockPointerType(VD->
getType()))
4242 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4247 for (
const ValueDecl *VD : BlockByRefDecls) {
4255 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4260 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4262 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4263 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4270 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4272 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4273 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4283std::string RewriteModernObjC::SynthesizeBlockDescriptor(
4284 const std::string &DescTag,
const std::string &ImplTag,
int i,
4285 StringRef FunName,
unsigned hasCopy) {
4286 std::string S =
"\nstatic struct " + DescTag;
4288 S +=
" {\n size_t reserved;\n";
4289 S +=
" size_t Block_size;\n";
4291 S +=
" void (*copy)(struct ";
4292 S += ImplTag; S +=
"*, struct ";
4293 S += ImplTag; S +=
"*);\n";
4295 S +=
" void (*dispose)(struct ";
4296 S += ImplTag; S +=
"*);\n";
4300 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4303 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4304 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4310void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4311 StringRef FunName) {
4312 bool RewriteSC = (GlobalVarDecl &&
4317 std::string SC(
" void __");
4320 InsertText(FunLocStart, SC);
4324 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4325 CollectBlockDeclRefInfo(Blocks[i]);
4328 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4331 BlockDeclRefs.push_back(Exp);
4332 if (!VD->
hasAttr<BlocksAttr>()) {
4333 BlockByCopyDecls.insert(VD);
4337 BlockByRefDecls.insert(VD);
4343 ImportedBlockDecls.insert(VD);
4346 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4347 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4349 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4351 InsertText(FunLocStart, CI);
4353 std::string
CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4355 InsertText(FunLocStart, CF);
4357 if (ImportedBlockDecls.size()) {
4358 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4359 InsertText(FunLocStart, HF);
4361 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4362 ImportedBlockDecls.size() > 0);
4363 InsertText(FunLocStart, BD);
4365 BlockDeclRefs.clear();
4366 BlockByRefDecls.clear();
4367 BlockByCopyDecls.clear();
4368 ImportedBlockDecls.clear();
4382 InsertText(FunLocStart, SC);
4384 if (GlobalConstructionExp) {
4388 std::string
Tag =
"__";
4390 Tag +=
"_block_impl_";
4391 Tag += utostr(Blocks.size()-1);
4392 std::string globalBuf =
"static ";
4393 globalBuf +=
Tag; globalBuf +=
" ";
4396 llvm::raw_string_ostream constructorExprBuf(SStr);
4397 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4401 InsertText(FunLocStart, globalBuf);
4402 GlobalConstructionExp =
nullptr;
4406 InnerDeclRefsCount.clear();
4407 InnerDeclRefs.clear();
4408 RewrittenBlockExprs.clear();
4411void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4413 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4415 StringRef FuncName = FD->
getName();
4417 SynthesizeBlockLiterals(FunLocStart, FuncName);
4420static void BuildUniqueMethodName(std::string &Name,
4423 Name = std::string(IFace->
getName());
4426 std::string::size_type loc = 0;
4427 while ((loc = Name.find(
':', loc)) != std::string::npos)
4428 Name.replace(loc, 1,
"_");
4431void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4435 std::string FuncName;
4436 BuildUniqueMethodName(FuncName, MD);
4437 SynthesizeBlockLiterals(FunLocStart, FuncName);
4440void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4441 for (
Stmt *SubStmt : S->children())
4443 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4444 GetBlockDeclRefExprs(CBE->getBody());
4446 GetBlockDeclRefExprs(SubStmt);
4451 HasLocalVariableExternalStorage(DRE->
getDecl()))
4453 BlockDeclRefs.push_back(DRE);
4456void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4458 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4459 for (
Stmt *SubStmt : S->children())
4461 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4462 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4463 GetInnerBlockDeclRefExprs(CBE->getBody(),
4468 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4471 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4473 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4475 InnerBlockDeclRefs.push_back(DRE);
4477 if (Var->isFunctionOrMethodVarDecl())
4478 ImportedLocalExternalDecls.insert(Var);
4486bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4488 convertBlockPointerToFunctionPointer(T);
4494 T = convertFunctionTypeOfBlocks(FT);
4495 T = Context->getPointerType(T);
4500 convertToUnqualifiedObjCType(T);
4514 bool modified = convertObjCTypeToCStyleType(Res);
4520 if (convertObjCTypeToCStyleType(t))
4522 ArgTypes.push_back(t);
4527 FuncType = getSimpleFunctionType(Res, ArgTypes);
4532Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4536 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4538 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4541 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4542 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4544 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4547 dyn_cast<ConditionalOperator>(BlockExp)) {
4548 Expr *LHSExp = CEXPR->getLHS();
4549 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4550 Expr *RHSExp = CEXPR->getRHS();
4551 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4552 Expr *CONDExp = CEXPR->getCond();
4557 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4560 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4563 assert(
false &&
"RewriteBlockClass: Bad type");
4565 assert(CPT &&
"RewriteBlockClass: Bad type");
4567 assert(FT &&
"RewriteBlockClass: Bad type");
4571 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
4573 &Context->Idents.get(
"__block_impl"));
4574 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4580 ArgTypes.push_back(PtrBlock);
4585 if (!convertBlockPointerToFunctionPointer(t))
4586 convertToUnqualifiedObjCType(t);
4587 ArgTypes.push_back(t);
4591 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4593 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4595 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4597 const_cast<Expr*
>(BlockExp));
4605 &Context->Idents.get(
"FuncPtr"),
4606 Context->VoidPtrTy,
nullptr,
4610 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4612 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4618 BlkExprs.push_back(BlkCast);
4622 BlkExprs.push_back(*I);
4625 CallExpr::Create(*Context, PE, BlkExprs, Exp->
getType(), VK_PRValue,
4643Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4648 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4652 &Context->Idents.get(
"__forwarding"),
4653 Context->VoidPtrTy,
nullptr,
4657 *Context, DeclRefExp, isArrow, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4659 StringRef Name = VD->
getName();
4661 &Context->Idents.get(Name),
4662 Context->VoidPtrTy,
nullptr,
4665 ME = MemberExpr::CreateImplicit(*Context, ME,
true, FD, DeclRefExp->
getType(),
4666 VK_LValue, OK_Ordinary);
4672 ReplaceStmt(DeclRefExp, PE);
4679Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4681 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4682 if (!ImportedLocalExternalDecls.count(Var))
4684 Expr *Exp = UnaryOperator::Create(
4690 ReplaceStmt(DRE, PE);
4702 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4705 const char *startBuf =
SM->getCharacterData(LocStart);
4706 const char *endBuf =
SM->getCharacterData(LocEnd);
4709 if (isa<TypeOfExprType>(TypePtr)) {
4710 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4712 std::string TypeAsString =
"(";
4713 RewriteBlockPointerType(TypeAsString, QT);
4714 TypeAsString +=
")";
4715 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4719 const char *argPtr = startBuf;
4721 while (*argPtr++ && (argPtr < endBuf)) {
4726 ReplaceText(LocStart, 1,
"*");
4732void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4734 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4735 CastKind != CK_AnyPointerToBlockPointerCast)
4739 (void)convertBlockPointerToFunctionPointer(QT);
4740 std::string TypeString(QT.
getAsString(Context->getPrintingPolicy()));
4741 std::string Str =
"(";
4747void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4749 unsigned parenCount = 0;
4752 const char *startBuf =
SM->getCharacterData(DeclLoc);
4753 const char *startArgList = strchr(startBuf,
'(');
4755 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4760 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4762 const char *argPtr = startArgList;
4764 while (*argPtr++ && parenCount) {
4769 ReplaceText(DeclLoc, 1,
"*");
4781bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4788 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4793 if (isTopLevelBlockPointerType(I))
4799bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4806 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4811 if (I->isObjCQualifiedIdType())
4813 if (I->isObjCObjectPointerType() &&
4814 I->getPointeeType()->isObjCQualifiedInterfaceType())
4822void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4823 const char *&RParen) {
4824 const char *argPtr = strchr(Name,
'(');
4825 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4829 unsigned parenCount = 1;
4831 while (*argPtr && parenCount) {
4833 case '(': parenCount++;
break;
4834 case ')': parenCount--;
break;
4837 if (parenCount) argPtr++;
4839 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4843void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4845 RewriteBlockPointerFunctionArgs(FD);
4851 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4854 DeclT = TDD->getUnderlyingType();
4855 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4858 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4860 const char *startBuf =
SM->getCharacterData(DeclLoc);
4861 const char *endBuf = startBuf;
4863 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4867 unsigned OrigLength=0;
4870 if (*startBuf ==
'^') {
4876 while (*startBuf !=
')') {
4884 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4885 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4889 startBuf =
SM->getCharacterData(DeclLoc);
4890 const char *argListBegin, *argListEnd;
4891 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4892 while (argListBegin < argListEnd) {
4893 if (*argListBegin ==
'^')
4895 else if (*argListBegin ==
'<') {
4897 buf += *argListBegin++;
4899 while (*argListBegin !=
'>') {
4900 buf += *argListBegin++;
4903 buf += *argListBegin;
4907 buf += *argListBegin;
4914 ReplaceText(Start, OrigLength, buf);
4937std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4940 if (CopyDestroyCache.count(flag))
4942 CopyDestroyCache.insert(flag);
4943 S =
"static void __Block_byref_id_object_copy_";
4945 S +=
"(void *dst, void *src) {\n";
4950 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4951 unsigned VoidPtrSize =
4952 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4954 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4955 S +=
" _Block_object_assign((char*)dst + ";
4956 S += utostr(offset);
4957 S +=
", *(void * *) ((char*)src + ";
4958 S += utostr(offset);
4963 S +=
"static void __Block_byref_id_object_dispose_";
4965 S +=
"(void *src) {\n";
4966 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4967 S += utostr(offset);
4992void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5001 const char *startBuf =
SM->getCharacterData(DeclLoc);
5003 X =
SM->getExpansionLoc(
X);
5004 const char *endBuf =
SM->getCharacterData(
X);
5006 std::string ByrefType;
5007 RewriteByRefString(ByrefType, Name, ND,
true);
5008 ByrefType +=
" {\n";
5009 ByrefType +=
" void *__isa;\n";
5010 RewriteByRefString(ByrefType, Name, ND);
5011 ByrefType +=
" *__forwarding;\n";
5012 ByrefType +=
" int __flags;\n";
5013 ByrefType +=
" int __size;\n";
5017 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
5018 if (HasCopyAndDispose) {
5019 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5020 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5024 (void)convertBlockPointerToFunctionPointer(T);
5025 T.getAsStringInternal(Name, Context->getPrintingPolicy());
5027 ByrefType +=
" " + Name +
";\n";
5028 ByrefType +=
"};\n";
5032 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5034 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5037 InsertText(FunLocStart, ByrefType);
5043 if (HasCopyAndDispose) {
5051 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5059 bool hasInit = (ND->
getInit() !=
nullptr);
5070 if (HasCopyAndDispose)
5074 RewriteByRefString(ByrefType, Name, ND);
5075 std::string ForwardingCastType(
"(");
5076 ForwardingCastType += ByrefType +
" *)";
5077 ByrefType +=
" " + Name +
" = {(void*)";
5078 ByrefType += utostr(isa);
5079 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5080 ByrefType += utostr(flags);
5082 ByrefType +=
"sizeof(";
5083 RewriteByRefString(ByrefType, Name, ND);
5085 if (HasCopyAndDispose) {
5086 ByrefType +=
", __Block_byref_id_object_copy_";
5087 ByrefType += utostr(flag);
5088 ByrefType +=
", __Block_byref_id_object_dispose_";
5089 ByrefType += utostr(flag);
5097 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5098 const char *commaBuf = startDeclBuf;
5099 while (*commaBuf !=
',')
5101 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5103 startBuf = commaBuf;
5107 ByrefType +=
"};\n";
5108 unsigned nameSize = Name.size();
5113 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5120 startLoc = ECE->getLParenLoc();
5122 startLoc =
E->getBeginLoc();
5123 startLoc =
SM->getExpansionLoc(startLoc);
5124 endBuf =
SM->getCharacterData(startLoc);
5125 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5127 const char separator = lastDecl ?
';' :
',';
5128 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5129 const char *separatorBuf = strchr(startInitializerBuf, separator);
5130 assert((*separatorBuf == separator) &&
5131 "RewriteByRefVar: can't find ';' or ','");
5135 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5139void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5141 GetBlockDeclRefExprs(Exp->
getBody());
5142 if (BlockDeclRefs.size()) {
5144 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5145 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>())
5146 BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
5148 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5149 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>())
5150 BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
5152 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5153 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5154 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5155 BlockDeclRefs[i]->getType()->isBlockPointerType())
5156 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5160FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5162 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5172 Blocks.push_back(Exp);
5174 CollectBlockDeclRefInfo(Exp);
5177 int countOfInnerDecls = 0;
5178 if (!InnerBlockDeclRefs.empty()) {
5179 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5182 if (!VD->
hasAttr<BlocksAttr>() && BlockByCopyDecls.insert(VD)) {
5186 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5187 BlockDeclRefs.push_back(Exp);
5189 if (VD->
hasAttr<BlocksAttr>() && BlockByRefDecls.insert(VD)) {
5190 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5191 BlockDeclRefs.push_back(Exp);
5195 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5196 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5197 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5198 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5199 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5201 InnerDeclRefsCount.push_back(countOfInnerDecls);
5203 std::string FuncName;
5207 else if (CurMethodDef)
5208 BuildUniqueMethodName(FuncName, CurMethodDef);
5209 else if (GlobalVarDecl)
5212 bool GlobalBlockExpr =
5215 if (GlobalBlockExpr && !GlobalVarDecl) {
5217 GlobalBlockExpr =
false;
5220 std::string BlockNumber = utostr(Blocks.size()-1);
5222 std::string
Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5225 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5226 QualType FType = Context->getPointerType(BFT);
5234 if (GlobalBlockExpr)
5238 Tag += FuncName +
"_block_impl_" + BlockNumber;
5240 FD = SynthBlockInitFunctionDecl(Tag);
5247 FD = SynthBlockInitFunctionDecl(Func);
5252 InitExprs.push_back(castExpr);
5255 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5257 VarDecl *NewVD = VarDecl::Create(
5259 &Context->Idents.get(DescData), Context->VoidPtrTy,
nullptr, SC_Static);
5262 new (Context)
DeclRefExpr(*Context, NewVD,
false, Context->VoidPtrTy,
5264 UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue,
5266 InitExprs.push_back(DescRefExpr);
5269 if (BlockDeclRefs.size()) {
5272 for (
ValueDecl *VD : BlockByCopyDecls) {
5273 if (isObjCType(VD->
getType())) {
5275 FD = SynthBlockInitFunctionDecl(VD->
getName());
5278 if (HasLocalVariableExternalStorage(VD)) {
5280 QT = Context->getPointerType(QT);
5281 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5282 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5286 }
else if (isTopLevelBlockPointerType(VD->
getType())) {
5287 FD = SynthBlockInitFunctionDecl(VD->
getName());
5290 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5293 FD = SynthBlockInitFunctionDecl(VD->
getName());
5296 if (HasLocalVariableExternalStorage(VD)) {
5298 QT = Context->getPointerType(QT);
5299 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5300 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5305 InitExprs.push_back(Exp);
5310 std::string RecName;
5311 RewriteByRefString(RecName, Name, ND,
true);
5313 +
sizeof(
"struct"));
5315 RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
5317 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5318 QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5320 FD = SynthBlockInitFunctionDecl(ND->
getName());
5323 bool isNestedCapturedVar =
false;
5324 for (
const auto &CI : block->
captures()) {
5325 const VarDecl *variable = CI.getVariable();
5326 if (variable == ND && CI.isNested()) {
5327 assert(CI.isByRef() &&
5328 "SynthBlockInitExpr - captured block variable is not byref");
5329 isNestedCapturedVar =
true;
5335 if (!isNestedCapturedVar)
5336 Exp = UnaryOperator::Create(
5337 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5338 Context->getPointerType(Exp->
getType()), VK_PRValue, OK_Ordinary,
5340 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5341 InitExprs.push_back(Exp);
5344 if (ImportedBlockDecls.size()) {
5348 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5349 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag),
5351 InitExprs.push_back(FlagExp);
5353 NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
5356 if (GlobalBlockExpr) {
5357 assert (!GlobalConstructionExp &&
5358 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5359 GlobalConstructionExp = NewRep;
5363 NewRep = UnaryOperator::Create(
5364 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5365 Context->getPointerType(NewRep->
getType()), VK_PRValue, OK_Ordinary,
5367 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5373 BlockDeclRefs.clear();
5374 BlockByRefDecls.clear();
5375 BlockByCopyDecls.clear();
5376 ImportedBlockDecls.clear();
5380bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5382 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5383 return CS->getElement() == DS;
5391Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5392 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5393 isa<DoStmt>(S) || isa<ForStmt>(S))
5395 else if (isa<ObjCForCollectionStmt>(S)) {
5397 ObjCBcLabelNo.push_back(++BcLabelCount);
5404 return RewritePropertyOrImplicitSetter(PseudoOp);
5406 return RewritePropertyOrImplicitGetter(PseudoOp);
5408 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5409 return RewriteObjCIvarRefExpr(IvarRefExpr);
5411 else if (isa<OpaqueValueExpr>(S))
5412 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5417 for (
Stmt *&childStmt : S->children())
5419 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5421 childStmt = newStmt;
5425 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5428 InnerContexts.insert(BE->getBlockDecl());
5429 ImportedLocalExternalDecls.clear();
5430 GetInnerBlockDeclRefExprs(BE->getBody(),
5431 InnerBlockDeclRefs, InnerContexts);
5433 Stmt *SaveCurrentBody = CurrentBody;
5434 CurrentBody = BE->getBody();
5435 PropParentMap =
nullptr;
5441 bool saveDisableReplaceStmt = DisableReplaceStmt;
5442 DisableReplaceStmt =
false;
5443 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5444 DisableReplaceStmt = saveDisableReplaceStmt;
5445 CurrentBody = SaveCurrentBody;
5446 PropParentMap =
nullptr;
5447 ImportedLocalExternalDecls.clear();
5449 std::string Str =
Rewrite.getRewrittenText(BE->getSourceRange());
5450 RewrittenBlockExprs[BE] = Str;
5452 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5455 ReplaceStmt(S, blockTranscribed);
5456 return blockTranscribed;
5460 return RewriteAtEncode(AtEncode);
5463 return RewriteAtSelector(AtSelector);
5466 return RewriteObjCStringLiteral(AtString);
5469 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5472 return RewriteObjCBoxedExpr(BoxedExpr);
5475 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5478 dyn_cast<ObjCDictionaryLiteral>(S))
5479 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5487 const char *startBuf =
SM->getCharacterData(startLoc);
5488 const char *endBuf =
SM->getCharacterData(endLoc);
5490 std::string messString;
5491 messString +=
"// ";
5492 messString.append(startBuf, endBuf-startBuf+1);
5501 return RewriteMessageExpr(MessExpr);
5505 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5506 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5510 return RewriteObjCTryStmt(StmtTry);
5513 return RewriteObjCSynchronizedStmt(StmtTry);
5516 return RewriteObjCThrowStmt(StmtThrow);
5519 return RewriteObjCProtocolExpr(ProtocolExp);
5522 dyn_cast<ObjCForCollectionStmt>(S))
5523 return RewriteObjCForCollectionStmt(StmtForCollection,
5526 dyn_cast<BreakStmt>(S))
5527 return RewriteBreakStmt(StmtBreakStmt);
5529 dyn_cast<ContinueStmt>(S))
5530 return RewriteContinueStmt(StmtContinueStmt);
5534 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5544 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5545 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5551 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5552 if (isTopLevelBlockPointerType(ND->
getType()))
5553 RewriteBlockPointerDecl(ND);
5555 CheckFunctionPointerDecl(ND->
getType(), ND);
5556 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5557 if (VD->
hasAttr<BlocksAttr>()) {
5558 static unsigned uniqueByrefDeclCount = 0;
5559 assert(!BlockByRefDeclNo.count(ND) &&
5560 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5561 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5562 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5565 RewriteTypeOfDecl(VD);
5569 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5570 RewriteBlockPointerDecl(TD);
5572 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5578 RewriteObjCQualifiedInterfaceTypes(CE);
5580 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5581 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5582 assert(!Stmts.empty() &&
"Statement stack is empty");
5583 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5584 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5585 &&
"Statement stack mismatch");
5589 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5591 if (VD->
hasAttr<BlocksAttr>())
5592 return RewriteBlockDeclRefExpr(DRE);
5593 if (HasLocalVariableExternalStorage(VD))
5594 return RewriteLocalVariableExternalStorage(DRE);
5597 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5599 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5600 ReplaceStmt(S, BlockCall);
5605 RewriteCastExpr(CE);
5608 RewriteImplicitCastObjCExpr(ICE);
5618 llvm::raw_string_ostream Buf(SStr);
5619 Replacement->printPretty(Buf);
5620 const std::string &Str = Buf.str();
5622 printf(
"CAST = %s\n", &Str[0]);
5632void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5633 for (
auto *FD : RD->
fields()) {
5634 if (isTopLevelBlockPointerType(FD->
getType()))
5635 RewriteBlockPointerDecl(FD);
5638 RewriteObjCQualifiedInterfaceTypes(FD);
5644void RewriteModernObjC::HandleDeclInMainFile(
Decl *
D) {
5645 switch (
D->getKind()) {
5646 case Decl::Function: {
5654 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5661 CurFunctionDef = FD;
5664 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5666 CurrentBody =
nullptr;
5667 if (PropParentMap) {
5668 delete PropParentMap;
5669 PropParentMap =
nullptr;
5673 InsertBlockLiteralsWithinFunction(FD);
5674 RewriteLineDirective(
D);
5675 CurFunctionDef =
nullptr;
5679 case Decl::ObjCMethod: {
5685 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5687 CurrentBody =
nullptr;
5688 if (PropParentMap) {
5689 delete PropParentMap;
5690 PropParentMap =
nullptr;
5692 InsertBlockLiteralsWithinMethod(MD);
5693 RewriteLineDirective(
D);
5694 CurMethodDef =
nullptr;
5698 case Decl::ObjCImplementation: {
5700 ClassImplementation.push_back(CI);
5703 case Decl::ObjCCategoryImpl: {
5705 CategoryImplementation.push_back(CI);
5710 RewriteObjCQualifiedInterfaceTypes(VD);
5711 if (isTopLevelBlockPointerType(VD->
getType()))
5712 RewriteBlockPointerDecl(VD);
5714 CheckFunctionPointerDecl(VD->
getType(), VD);
5717 RewriteCastExpr(CE);
5723 RewriteRecordBody(RD);
5728 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5729 CurrentBody =
nullptr;
5730 if (PropParentMap) {
5731 delete PropParentMap;
5732 PropParentMap =
nullptr;
5735 GlobalVarDecl =
nullptr;
5739 RewriteCastExpr(CE);
5744 case Decl::TypeAlias:
5745 case Decl::Typedef: {
5747 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5748 RewriteBlockPointerDecl(TD);
5750 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5752 RewriteObjCQualifiedInterfaceTypes(TD);
5756 case Decl::CXXRecord:
5757 case Decl::Record: {
5760 RewriteRecordBody(RD);
5772static void Write_ProtocolExprReferencedMetadata(
ASTContext *Context,
5774 std::string &Result) {
5776 if (Context->getLangOpts().MicrosoftExt)
5777 Result +=
"static ";
5778 Result +=
"struct _protocol_t *";
5779 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5786void RewriteModernObjC::HandleTranslationUnit(
ASTContext &C) {
5792 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5797 HandleTopLevelSingleDecl(FDecl);
5803 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5804 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5807 InsertText(
SM->getLocForStartOfFile(MainFileID), Preamble,
false);
5809 if (ClassImplementation.size() || CategoryImplementation.size())
5810 RewriteImplementations();
5812 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5818 RewriteInterfaceDecl(CDecl);
5823 if (
const RewriteBuffer *RewriteBuf =
5824 Rewrite.getRewriteBufferFor(MainFileID)) {
5826 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5828 llvm::errs() <<
"No changes\n";
5831 if (ClassImplementation.size() || CategoryImplementation.size() ||
5832 ProtocolExprDecls.size()) {
5834 std::string ResultStr;
5835 RewriteMetaDataIntoBuffer(ResultStr);
5837 *OutFile << ResultStr;
5841 std::string ResultStr;
5842 WriteImageInfo(ResultStr);
5843 *OutFile << ResultStr;
5848void RewriteModernObjC::Initialize(
ASTContext &context) {
5849 InitializeCommon(context);
5859 Preamble +=
"struct objc_selector; struct objc_class;\n";
5860 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5861 Preamble +=
"\n\tstruct objc_object *superClass; ";
5863 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5864 Preamble +=
": object(o), superClass(s) {} ";
5867 if (LangOpts.MicrosoftExt) {
5870 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5871 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5872 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5873 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5874 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5876 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5877 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5878 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5879 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5883 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5884 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5885 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5888 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5889 Preamble +=
"typedef struct objc_object Protocol;\n";
5890 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5892 if (LangOpts.MicrosoftExt) {
5893 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5894 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5897 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5899 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5900 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5901 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5902 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5903 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5905 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5907 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5908 Preamble +=
"(struct objc_class *);\n";
5909 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5911 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5913 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5914 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5915 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5917 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5919 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5921 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5922 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5923 Preamble +=
"unsigned long state;\n\t";
5924 Preamble +=
"void **itemsPtr;\n\t";
5925 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5926 Preamble +=
"unsigned long extra[5];\n};\n";
5927 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5928 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5930 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5931 Preamble +=
"struct __NSConstantStringImpl {\n";
5936 Preamble +=
" long long length;\n";
5941 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5942 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5944 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5946 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5949 Preamble +=
"#ifndef BLOCK_IMPL\n";
5950 Preamble +=
"#define BLOCK_IMPL\n";
5951 Preamble +=
"struct __block_impl {\n";
5957 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5958 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5959 Preamble +=
"extern \"C\" __declspec(dllexport) "
5960 "void _Block_object_assign(void *, const void *, const int);\n";
5961 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5962 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5963 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
5965 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
5966 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
5967 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
5968 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
5971 if (LangOpts.MicrosoftExt) {
5972 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
5973 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
5974 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
5975 Preamble +=
"#define __attribute__(X)\n";
5990 Preamble +=
"\n#include <stdarg.h>\n";
5991 Preamble +=
"struct __NSContainer_literal {\n";
5993 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
5995 Preamble +=
"\tva_start(marker, count);\n";
5996 Preamble +=
"\tarr = new void *[count];\n";
5997 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
5998 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
5999 Preamble +=
"\tva_end( marker );\n";
6001 Preamble +=
" ~__NSContainer_literal() {\n";
6007 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6008 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6009 Preamble +=
"struct __AtAutoreleasePool {\n";
6010 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6011 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6012 Preamble +=
" void * atautoreleasepoolobj;\n";
6017 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6022void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6023 std::string &Result) {
6024 Result +=
"__OFFSETOFIVAR__(struct ";
6026 if (LangOpts.MicrosoftExt)
6030 ObjCIvarBitfieldGroupDecl(ivar, Result);
6138static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6139 static bool meta_data_declared =
false;
6140 if (meta_data_declared)
6143 Result +=
"\nstruct _prop_t {\n";
6144 Result +=
"\tconst char *name;\n";
6145 Result +=
"\tconst char *attributes;\n";
6148 Result +=
"\nstruct _protocol_t;\n";
6150 Result +=
"\nstruct _objc_method {\n";
6151 Result +=
"\tstruct objc_selector * _cmd;\n";
6152 Result +=
"\tconst char *method_type;\n";
6153 Result +=
"\tvoid *_imp;\n";
6156 Result +=
"\nstruct _protocol_t {\n";
6157 Result +=
"\tvoid * isa; // NULL\n";
6158 Result +=
"\tconst char *protocol_name;\n";
6159 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6160 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6161 Result +=
"\tconst struct method_list_t *class_methods;\n";
6162 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6163 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6164 Result +=
"\tconst struct _prop_list_t * properties;\n";
6165 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6166 Result +=
"\tconst unsigned int flags; // = 0\n";
6167 Result +=
"\tconst char ** extendedMethodTypes;\n";
6170 Result +=
"\nstruct _ivar_t {\n";
6171 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6172 Result +=
"\tconst char *name;\n";
6173 Result +=
"\tconst char *type;\n";
6174 Result +=
"\tunsigned int alignment;\n";
6175 Result +=
"\tunsigned int size;\n";
6178 Result +=
"\nstruct _class_ro_t {\n";
6179 Result +=
"\tunsigned int flags;\n";
6180 Result +=
"\tunsigned int instanceStart;\n";
6181 Result +=
"\tunsigned int instanceSize;\n";
6182 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6183 if (Triple.getArch() == llvm::Triple::x86_64)
6184 Result +=
"\tunsigned int reserved;\n";
6185 Result +=
"\tconst unsigned char *ivarLayout;\n";
6186 Result +=
"\tconst char *name;\n";
6187 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6188 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6189 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6190 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6191 Result +=
"\tconst struct _prop_list_t *properties;\n";
6194 Result +=
"\nstruct _class_t {\n";
6195 Result +=
"\tstruct _class_t *isa;\n";
6196 Result +=
"\tstruct _class_t *superclass;\n";
6197 Result +=
"\tvoid *cache;\n";
6198 Result +=
"\tvoid *vtable;\n";
6199 Result +=
"\tstruct _class_ro_t *ro;\n";
6202 Result +=
"\nstruct _category_t {\n";
6203 Result +=
"\tconst char *name;\n";
6204 Result +=
"\tstruct _class_t *cls;\n";
6205 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6206 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6207 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6208 Result +=
"\tconst struct _prop_list_t *properties;\n";
6211 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6212 Result +=
"#pragma warning(disable:4273)\n";
6213 meta_data_declared =
true;
6216static void Write_protocol_list_t_TypeDecl(std::string &Result,
6217 long super_protocol_count) {
6218 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6219 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6220 Result +=
"\tstruct _protocol_t *super_protocols[";
6221 Result += utostr(super_protocol_count); Result +=
"];\n";
6225static void Write_method_list_t_TypeDecl(std::string &Result,
6226 unsigned int method_count) {
6227 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6228 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6229 Result +=
"\tunsigned int method_count;\n";
6230 Result +=
"\tstruct _objc_method method_list[";
6231 Result += utostr(method_count); Result +=
"];\n";
6235static void Write__prop_list_t_TypeDecl(std::string &Result,
6236 unsigned int property_count) {
6237 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6238 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6239 Result +=
"\tunsigned int count_of_properties;\n";
6240 Result +=
"\tstruct _prop_t prop_list[";
6241 Result += utostr(property_count); Result +=
"];\n";
6245static void Write__ivar_list_t_TypeDecl(std::string &Result,
6246 unsigned int ivar_count) {
6247 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6248 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6249 Result +=
"\tunsigned int count;\n";
6250 Result +=
"\tstruct _ivar_t ivar_list[";
6251 Result += utostr(ivar_count); Result +=
"];\n";
6255static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6258 StringRef ProtocolName) {
6259 if (SuperProtocols.size() > 0) {
6260 Result +=
"\nstatic ";
6261 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6262 Result +=
" "; Result += VarName;
6263 Result += ProtocolName;
6264 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6265 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6266 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6268 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6278static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6282 StringRef TopLevelDeclName,
6284 if (Methods.size() > 0) {
6285 Result +=
"\nstatic ";
6286 Write_method_list_t_TypeDecl(Result, Methods.size());
6287 Result +=
" "; Result += VarName;
6288 Result += TopLevelDeclName;
6289 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6290 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6291 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6292 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6295 Result +=
"\t{{(struct objc_selector *)\"";
6297 Result +=
"\t{(struct objc_selector *)\"";
6298 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6300 std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(MD);
6301 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6306 Result +=
"(void *)";
6307 Result += RewriteObj.MethodInternalNames[MD];
6318static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6321 const Decl *Container,
6323 StringRef ProtocolName) {
6324 if (Properties.size() > 0) {
6325 Result +=
"\nstatic ";
6326 Write__prop_list_t_TypeDecl(Result, Properties.size());
6327 Result +=
" "; Result += VarName;
6328 Result += ProtocolName;
6329 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6330 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6331 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6332 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6338 Result += PropDecl->
getName(); Result +=
"\",";
6339 std::string PropertyTypeString =
6340 Context->getObjCEncodingForPropertyDecl(PropDecl, Container);
6341 std::string QuotePropertyTypeString;
6342 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6343 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6358 OBJC2_CLS_HIDDEN = 0x10,
6359 CLS_EXCEPTION = 0x20,
6362 CLS_HAS_IVAR_RELEASER = 0x40,
6364 CLS_COMPILED_BY_ARC = 0x80
6367static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6369 const std::string &InstanceStart,
6370 const std::string &InstanceSize,
6376 StringRef ClassName) {
6377 Result +=
"\nstatic struct _class_ro_t ";
6378 Result += VarName; Result += ClassName;
6379 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6381 Result += llvm::utostr(flags); Result +=
", ";
6382 Result += InstanceStart; Result +=
", ";
6383 Result += InstanceSize; Result +=
", \n";
6385 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6386 if (Triple.getArch() == llvm::Triple::x86_64)
6388 Result +=
"(unsigned int)0, \n\t";
6390 Result +=
"0, \n\t";
6391 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6392 bool metaclass = ((flags & CLS_META) != 0);
6393 if (baseMethods.size() > 0) {
6394 Result +=
"(const struct _method_list_t *)&";
6396 Result +=
"_OBJC_$_CLASS_METHODS_";
6398 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6399 Result += ClassName;
6403 Result +=
"0, \n\t";
6405 if (!metaclass && baseProtocols.size() > 0) {
6406 Result +=
"(const struct _objc_protocol_list *)&";
6407 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6411 Result +=
"0, \n\t";
6413 if (!metaclass && ivars.size() > 0) {
6414 Result +=
"(const struct _ivar_list_t *)&";
6415 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6419 Result +=
"0, \n\t";
6422 Result +=
"0, \n\t";
6423 if (!metaclass && Properties.size() > 0) {
6424 Result +=
"(const struct _prop_list_t *)&";
6425 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6434static void Write_class_t(
ASTContext *Context, std::string &Result,
6448 if (metaclass && rootClass) {
6451 Result +=
"extern \"C\" ";
6453 Result +=
"__declspec(dllexport) ";
6455 Result +=
"__declspec(dllimport) ";
6457 Result +=
"struct _class_t OBJC_CLASS_$_";
6465 Result +=
"extern \"C\" ";
6467 Result +=
"__declspec(dllexport) ";
6469 Result +=
"__declspec(dllimport) ";
6471 Result +=
"struct _class_t ";
6476 if (metaclass && RootClass != SuperClass) {
6477 Result +=
"extern \"C\" ";
6479 Result +=
"__declspec(dllexport) ";
6481 Result +=
"__declspec(dllimport) ";
6483 Result +=
"struct _class_t ";
6490 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6492 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6496 Result +=
"0, // &"; Result += VarName;
6499 Result +=
"0, // &"; Result += VarName;
6504 Result +=
"0, // &"; Result += VarName;
6512 Result +=
"0, // &OBJC_METACLASS_$_";
6516 Result +=
"0, // &"; Result += VarName;
6523 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6524 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6526 Result +=
"&_OBJC_METACLASS_RO_$_";
6528 Result +=
"&_OBJC_CLASS_RO_$_";
6530 Result +=
",\n};\n";
6540 Result +=
"static void OBJC_CLASS_SETUP_$_";
6542 Result +=
"(void ) {\n";
6544 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6548 Result +=
".superclass = ";
6550 Result +=
"&OBJC_CLASS_$_";
6552 Result +=
"&OBJC_METACLASS_$_";
6557 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6560 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6565 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6570 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6574static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6575 std::string &Result,
6582 StringRef CatName = CatDecl->
getName();
6583 StringRef ClassName = ClassDecl->
getName();
6587 Result +=
"extern \"C\" ";
6589 Result +=
"__declspec(dllexport) ";
6591 Result +=
"__declspec(dllimport) ";
6593 Result +=
"struct _class_t ";
6594 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6597 Result +=
"\nstatic struct _category_t ";
6598 Result +=
"_OBJC_$_CATEGORY_";
6599 Result += ClassName; Result +=
"_$_"; Result += CatName;
6600 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6602 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6603 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6605 if (InstanceMethods.size() > 0) {
6606 Result +=
"\t(const struct _method_list_t *)&";
6607 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6608 Result += ClassName; Result +=
"_$_"; Result += CatName;
6614 if (ClassMethods.size() > 0) {
6615 Result +=
"\t(const struct _method_list_t *)&";
6616 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6617 Result += ClassName; Result +=
"_$_"; Result += CatName;
6623 if (RefedProtocols.size() > 0) {
6624 Result +=
"\t(const struct _protocol_list_t *)&";
6625 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6626 Result += ClassName; Result +=
"_$_"; Result += CatName;
6632 if (ClassProperties.size() > 0) {
6633 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6634 Result += ClassName; Result +=
"_$_"; Result += CatName;
6643 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6647 Result +=
"(void ) {\n";
6648 Result +=
"\t_OBJC_$_CATEGORY_";
6652 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6656static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6660 StringRef ProtocolName) {
6661 if (Methods.size() == 0)
6664 Result +=
"\nstatic const char *";
6665 Result += VarName; Result += ProtocolName;
6666 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6668 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6670 std::string MethodTypeString =
6671 Context->getObjCEncodingForMethodDecl(MD,
true);
6672 std::string QuoteMethodTypeString;
6673 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6674 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6683static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6685 std::string &Result,
6700 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6702 if (Context->getLangOpts().MicrosoftExt)
6703 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6705 if (!Context->getLangOpts().MicrosoftExt ||
6708 Result +=
"extern \"C\" unsigned long int ";
6710 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6711 if (Ivars[i]->isBitField())
6712 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6714 WriteInternalIvarName(CDecl, IvarDecl, Result);
6715 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6717 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6719 if (Ivars[i]->isBitField()) {
6721 SKIP_BITFIELDS(i , e, Ivars);
6726static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6731 if (OriginalIvars.size() > 0) {
6732 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6737 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6738 if (OriginalIvars[i]->isBitField()) {
6739 Ivars.push_back(OriginalIvars[i]);
6741 SKIP_BITFIELDS(i , e, OriginalIvars);
6744 Ivars.push_back(OriginalIvars[i]);
6747 Result +=
"\nstatic ";
6748 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6749 Result +=
" "; Result += VarName;
6751 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6752 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6753 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6754 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6760 Result +=
"(unsigned long int *)&";
6761 if (Ivars[i]->isBitField())
6762 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6764 WriteInternalIvarName(CDecl, IvarDecl, Result);
6768 if (Ivars[i]->isBitField())
6769 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6771 Result += IvarDecl->
getName();
6776 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6778 std::string IvarTypeString, QuoteIvarTypeString;
6779 Context->getObjCEncodingForType(IVQT, IvarTypeString,
6781 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6782 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6786 unsigned Align = Context->getTypeAlign(IVQT)/8;
6787 Align = llvm::Log2_32(Align);
6788 Result += llvm::utostr(Align); Result +=
", ";
6790 Result += llvm::utostr(
Size.getQuantity());
6801void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6802 std::string &Result) {
6807 WriteModernMetadataDeclarations(Context, Result);
6814 RewriteObjCProtocolMetaData(I, Result);
6817 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6818 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6821 OptInstanceMethods.push_back(MD);
6823 InstanceMethods.push_back(MD);
6829 OptClassMethods.push_back(MD);
6831 ClassMethods.push_back(MD);
6834 std::vector<ObjCMethodDecl *> AllMethods;
6835 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6836 AllMethods.push_back(InstanceMethods[i]);
6837 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6838 AllMethods.push_back(ClassMethods[i]);
6839 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6840 AllMethods.push_back(OptInstanceMethods[i]);
6841 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6842 AllMethods.push_back(OptClassMethods[i]);
6844 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6846 "_OBJC_PROTOCOL_METHOD_TYPES_",
6850 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6851 "_OBJC_PROTOCOL_REFS_",
6854 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6855 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6858 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6859 "_OBJC_PROTOCOL_CLASS_METHODS_",
6862 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6863 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6866 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6867 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6873 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
6875 "_OBJC_PROTOCOL_PROPERTIES_",
6880 if (LangOpts.MicrosoftExt)
6881 Result +=
"static ";
6882 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6884 Result +=
" __attribute__ ((used)) = {\n";
6886 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6887 if (SuperProtocols.size() > 0) {
6888 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6893 if (InstanceMethods.size() > 0) {
6894 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6900 if (ClassMethods.size() > 0) {
6901 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6907 if (OptInstanceMethods.size() > 0) {
6908 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6914 if (OptClassMethods.size() > 0) {
6915 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6921 if (ProtocolProperties.size() > 0) {
6922 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6928 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6931 if (AllMethods.size() > 0) {
6932 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6937 Result +=
"\t0\n};\n";
6939 if (LangOpts.MicrosoftExt)
6940 Result +=
"static ";
6941 Result +=
"struct _protocol_t *";
6942 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6948 llvm_unreachable(
"protocol already synthesized");
6956 if (OID->
hasAttr<ObjCExceptionAttr>())
6964 std::string &Result) {
6970 "Legacy implicit interface rewriting not supported in moder abi");
6972 WriteModernMetadataDeclarations(Context, Result);
6978 if (!IVD->getDeclName())
6980 IVars.push_back(IVD);
6983 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
6984 "_OBJC_$_INSTANCE_VARIABLES_",
6993 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
6995 if (!Prop->getPropertyIvarDecl())
7001 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7002 InstanceMethods.push_back(Getter);
7006 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7007 InstanceMethods.push_back(Setter);
7010 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7011 "_OBJC_$_INSTANCE_METHODS_",
7016 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7017 "_OBJC_$_CLASS_METHODS_",
7022 std::vector<ObjCProtocolDecl *> RefedProtocols;
7025 E = Protocols.
end();
7027 RefedProtocols.push_back(*I);
7030 RewriteObjCProtocolMetaData(*I, Result);
7033 Write_protocol_list_initializer(Context, Result,
7035 "_OBJC_CLASS_PROTOCOLS_$_",
7041 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7043 "_OBJC_$_PROP_LIST_",
7048 std::string InstanceSize;
7049 std::string InstanceStart;
7053 flags |= OBJC2_CLS_HIDDEN;
7058 InstanceSize =
"sizeof(struct _class_t)";
7059 InstanceStart = InstanceSize;
7060 Write__class_ro_t_initializer(Context, Result, flags,
7061 InstanceStart, InstanceSize,
7066 "_OBJC_METACLASS_RO_$_",
7072 flags |= OBJC2_CLS_HIDDEN;
7075 flags |= CLS_EXCEPTION;
7081 InstanceSize.clear();
7082 InstanceStart.clear();
7083 if (!ObjCSynthesizedStructs.count(CDecl)) {
7085 InstanceStart =
"0";
7088 InstanceSize =
"sizeof(struct ";
7090 InstanceSize +=
"_IMPL)";
7094 RewriteIvarOffsetComputation(IVD, InstanceStart);
7097 InstanceStart = InstanceSize;
7099 Write__class_ro_t_initializer(Context, Result, flags,
7100 InstanceStart, InstanceSize,
7105 "_OBJC_CLASS_RO_$_",
7108 Write_class_t(Context, Result,
7109 "OBJC_METACLASS_$_",
7112 Write_class_t(Context, Result,
7116 if (ImplementationIsNonLazy(IDecl))
7117 DefinedNonLazyClasses.push_back(CDecl);
7120void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7121 int ClsDefCount = ClassImplementation.size();
7124 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7125 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7126 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7127 for (
int i = 0; i < ClsDefCount; i++) {
7130 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7131 Result += CDecl->
getName(); Result +=
",\n";
7136void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7137 int ClsDefCount = ClassImplementation.size();
7138 int CatDefCount = CategoryImplementation.size();
7141 for (
int i = 0; i < ClsDefCount; i++)
7142 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7144 RewriteClassSetupInitHook(Result);
7147 for (
int i = 0; i < CatDefCount; i++)
7148 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7150 RewriteCategorySetupInitHook(Result);
7152 if (ClsDefCount > 0) {
7153 if (LangOpts.MicrosoftExt)
7154 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7155 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7156 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7158 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7159 "regular,no_dead_strip\")))= {\n";
7160 for (
int i = 0; i < ClsDefCount; i++) {
7161 Result +=
"\t&OBJC_CLASS_$_";
7162 Result += ClassImplementation[i]->getNameAsString();
7167 if (!DefinedNonLazyClasses.empty()) {
7168 if (LangOpts.MicrosoftExt)
7169 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7170 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7171 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7172 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7179 if (CatDefCount > 0) {
7180 if (LangOpts.MicrosoftExt)
7181 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7182 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7183 Result += llvm::utostr(CatDefCount); Result +=
"]";
7185 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7186 "regular,no_dead_strip\")))= {\n";
7187 for (
int i = 0; i < CatDefCount; i++) {
7188 Result +=
"\t&_OBJC_$_CATEGORY_";
7190 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7192 Result += CategoryImplementation[i]->getNameAsString();
7198 if (!DefinedNonLazyCategories.empty()) {
7199 if (LangOpts.MicrosoftExt)
7200 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7201 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7202 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7203 Result +=
"\t&_OBJC_$_CATEGORY_";
7205 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7207 Result += DefinedNonLazyCategories[i]->getNameAsString();
7214void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7215 if (LangOpts.MicrosoftExt)
7216 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7218 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7220 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7226 std::string &Result) {
7227 WriteModernMetadataDeclarations(Context, Result);
7234 FullCategoryName +=
"_$_";
7243 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7245 if (!Prop->getPropertyIvarDecl())
7251 InstanceMethods.push_back(Getter);
7255 InstanceMethods.push_back(Setter);
7258 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7259 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7260 FullCategoryName,
true);
7264 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7265 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7266 FullCategoryName,
true);
7274 RewriteObjCProtocolMetaData(I, Result);
7276 Write_protocol_list_initializer(Context, Result,
7278 "_OBJC_CATEGORY_PROTOCOLS_$_",
7284 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7286 "_OBJC_$_PROP_LIST_",
7289 Write_category_t(*
this, Context, Result,
7298 if (ImplementationIsNonLazy(IDecl))
7299 DefinedNonLazyCategories.push_back(CDecl);
7302void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7303 int CatDefCount = CategoryImplementation.size();
7306 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7307 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7308 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7309 for (
int i = 0; i < CatDefCount; i++) {
7313 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7314 Result += ClassDecl->
getName();
7324template<
typename MethodIterator>
7325void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7326 MethodIterator MethodEnd,
7327 bool IsInstanceMethod,
7329 StringRef ClassName,
7330 std::string &Result) {
7331 if (MethodBegin == MethodEnd)
return;
7333 if (!objc_impl_method) {
7340 Result +=
"\nstruct _objc_method {\n";
7341 Result +=
"\tSEL _cmd;\n";
7342 Result +=
"\tchar *method_types;\n";
7343 Result +=
"\tvoid *_imp;\n";
7346 objc_impl_method =
true;
7357 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7359 if (LangOpts.MicrosoftExt) {
7360 if (IsInstanceMethod)
7361 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7363 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7365 Result +=
"static struct {\n";
7366 Result +=
"\tstruct _objc_method_list *next_method;\n";
7367 Result +=
"\tint method_count;\n";
7368 Result +=
"\tstruct _objc_method method_list[";
7369 Result += utostr(NumMethods);
7370 Result +=
"];\n} _OBJC_";
7373 Result +=
"_METHODS_";
7374 Result += ClassName;
7375 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7377 Result +=
"_meth\")))= ";
7378 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7380 Result +=
"\t,{{(SEL)\"";
7381 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7382 std::string MethodTypeString;
7383 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7385 Result += MethodTypeString;
7386 Result +=
"\", (void *)";
7387 Result += MethodInternalNames[*MethodBegin];
7389 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7390 Result +=
"\t ,{(SEL)\"";
7391 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7392 std::string MethodTypeString;
7393 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7395 Result += MethodTypeString;
7396 Result +=
"\", (void *)";
7397 Result += MethodInternalNames[*MethodBegin];
7400 Result +=
"\t }\n};\n";
7409 DisableReplaceStmtScope S(*
this);
7410 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7416 Expr *Replacement = IV;
7421 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7426 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7429 std::string IvarOffsetName;
7430 if (
D->isBitField())
7431 ObjCIvarBitfieldGroupOffset(
D, IvarOffsetName);
7433 WriteInternalIvarName(clsDeclared,
D, IvarOffsetName);
7435 ReferencedIvars[clsDeclared].insert(
D);
7439 Context->getPointerType(Context->CharTy),
7444 Context->UnsignedLongTy,
nullptr,
7447 DeclRefExpr(*Context, NewVD,
false, Context->UnsignedLongTy,
7450 *Context, castExpr, DRE, BO_Add,
7451 Context->getPointerType(Context->CharTy), VK_PRValue, OK_Ordinary,
7458 if (
D->isBitField())
7459 IvarT = GetGroupRecordTypeForObjCIvarBitfield(
D);
7466 auto *CDecl = cast<ObjCContainerDecl>(
D->getDeclContext());
7470 std::string RecName = std::string(CDecl->
getName());
7475 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
7476 unsigned UnsignedIntSize =
7477 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
7478 Expr *
Zero = IntegerLiteral::Create(*Context,
7479 llvm::APInt(UnsignedIntSize, 0),
7481 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7486 &Context->Idents.get(
D->getNameAsString()),
7491 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
7492 IvarT = Context->getDecltypeType(ME, ME->
getType());
7495 convertObjCTypeToCStyleType(IvarT);
7496 QualType castT = Context->getPointerType(IvarT);
7498 castExpr = NoTypeInfoCStyleCastExpr(Context,
7503 Expr *Exp = UnaryOperator::Create(
7504 const_cast<ASTContext &
>(*Context), castExpr, UO_Deref, IvarT,
7510 if (
D->isBitField()) {
7513 &Context->Idents.get(
D->getNameAsString()),
7514 D->getType(),
nullptr,
7518 MemberExpr::CreateImplicit(*Context, PE,
false, FD,
7519 FD->
getType(), VK_LValue, OK_Ordinary);
7527 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::@1718::IndirectLocalPathEntry::EntryKind Kind
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the SourceManager interface.
__device__ __2f16 float c
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a block literal declaration, which is like an unnamed FunctionDecl.
param_iterator param_end()
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
param_iterator param_begin()
ArrayRef< Capture > captures() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const Stmt * getBody() const
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
const BlockDecl * getBlockDecl() const
QualType getPointeeType() const
BreakStmt - This represents a break.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
SourceLocation getRParenLoc() const
SourceLocation getLParenLoc() const
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
SourceLocation getBeginLoc() const
ConditionalOperator - The ?: ternary operator.
Represents the canonical version of C arrays with a specified constant size.
ContinueStmt - This represents a continue.
decl_iterator - Iterates through the declarations stored within this context.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isFileContext() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
void addDecl(Decl *D)
Add the declaration D into this context.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
SourceLocation getLocation() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
decl_iterator decl_begin()
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isFunctionPointerType() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
SourceLocation getTypeSpecStartLoc() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
bool hasErrorOccurred() const
enumerator_range enumerators() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isVariadic() const
Whether this function is variadic.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ArrayRef< QualType > param_types() const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a linkage specification.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Visibility getVisibility() const
Determines the visibility of this entity.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
ObjCMethodDecl * getArrayWithObjectsMethod() const
SourceLocation getEndLoc() const LLVM_READONLY
Represents Objective-C's @catch statement.
Represents Objective-C's @finally statement.
const Stmt * getFinallyBody() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
Represents Objective-C's @autoreleasepool Statement.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
SourceLocation getLocation() const
ObjCBoxedExpr - used for generalized expression boxing.
ObjCMethodDecl * getBoxingMethod() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
SourceLocation getIvarRBraceLoc() const
protocol_range protocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCContainerDecl - Represents a container for method declarations.
SourceRange getAtEndRange() const
instmeth_range instance_methods() const
instprop_range instance_properties() const
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
classmeth_range class_methods() const
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCMethodDecl * getDictWithObjectsMethod() const
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
Represents Objective-C's collection statement.
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
SourceLocation getIvarRBraceLoc() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
Represents an ObjC class declaration.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
const ObjCProtocolList & getReferencedProtocols() const
ObjCImplementationDecl * getImplementation() const
SourceLocation getEndOfDefinitionLoc() const
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
ObjCInterfaceDecl * getSuperClass() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCIvarRefExpr - A reference to an ObjC instance variable.
const Expr * getBase() const
ObjCList - This is a simple template class used to hold various lists of decls etc,...
An expression that sends a message to the given Objective-C object or class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getLeftLoc() const
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super',...
Selector getSelector() const
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or nullptr if the message is not a class m...
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const ObjCMethodDecl * getMethodDecl() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getRightLoc() const
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
CompoundStmt * getCompoundBody()
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
SourceLocation getEndLoc() const LLVM_READONLY
bool isSynthesizedAccessorStub() const
SourceLocation getBeginLoc() const LLVM_READONLY
Selector getSelector() const
bool isInstanceMethod() const
QualType getReturnType() const
ObjCImplementationControl getImplementationControl() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
Represents one property declaration in an Objective-C interface.
SourceLocation getAtLoc() const
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
Selector getSetterName() const
Selector getGetterName() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ObjCIvarDecl * getPropertyIvarDecl() const
Kind getPropertyImplementation() const
ObjCPropertyDecl * getPropertyDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
ObjCMethodDecl * getGetterMethodDecl() const
Represents an Objective-C protocol declaration.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
protocol_range protocols() const
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCProtocolDecl * getProtocol() const
ObjCSelectorExpr used for @selector in Objective-C.
Selector getSelector() const
ObjCStringLiteral, used for Objective-C string literals i.e.
StringLiteral * getString()
ParenExpr - This represents a parenthesized expression, e.g.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
unsigned getNumSemanticExprs() const
Expr * getSemanticExpr(unsigned index)
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isObjCGCWeak() const
true when Type is objc's weak.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Represents a struct/union/class.
field_range fields() const
virtual void completeDefinition()
Note that the definition of this type is now complete.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Rewriter - This is the main interface to the rewrite buffers.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getByteLength() const
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
The top declaration context.
Represents a declaration of a type.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Expr * getUnderlyingExpr() const
A container of type source information.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isEnumeralType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCQualifiedInterfaceType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const Expr * getInit() const
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Defines the clang::TargetInfo interface.
@ BLOCK_BYREF_CURRENT_MAX
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
@ CF
Indicates that the tracked object is a CF object.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
@ OK_Ordinary
An ordinary object is located at an address in memory.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
CastKind
CastKind - The kind of operation required for a conversion.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
int printf(__constant const char *st,...) __attribute__((format(printf
Extra information about a function prototype.
An element in an Objective-C dictionary literal.
Describes how types, statements, expressions, and declarations should be printed.
Iterator for iterating over Stmt * arrays that contain only T *.