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)
67 DiagnosticsEngine &Diags;
68 const LangOptions &LangOpts;
71 TranslationUnitDecl *TUDecl;
73 const char *MainFileStart, *MainFileEnd;
75 ParentMap *PropParentMap;
76 std::string InFileName;
77 std::unique_ptr<raw_ostream> OutFile;
80 TypeDecl *ProtocolTypeDecl;
81 VarDecl *GlobalVarDecl;
82 Expr *GlobalConstructionExp;
83 unsigned RewriteFailedDiag;
84 unsigned GlobalBlockRewriteFailedDiag;
86 unsigned NumObjCStringLiterals;
87 VarDecl *ConstantStringClassReference;
88 RecordDecl *NSStringRecord;
93 unsigned TryFinallyContainsReturnDiag;
95 ObjCMethodDecl *CurMethodDef;
96 RecordDecl *SuperStructDecl;
97 RecordDecl *ConstantStringDecl;
99 FunctionDecl *MsgSendFunctionDecl;
100 FunctionDecl *MsgSendSuperFunctionDecl;
101 FunctionDecl *MsgSendStretFunctionDecl;
102 FunctionDecl *MsgSendSuperStretFunctionDecl;
103 FunctionDecl *MsgSendFpretFunctionDecl;
104 FunctionDecl *GetClassFunctionDecl;
105 FunctionDecl *GetMetaClassFunctionDecl;
106 FunctionDecl *GetSuperClassFunctionDecl;
107 FunctionDecl *SelGetUidFunctionDecl;
108 FunctionDecl *CFStringFunctionDecl;
109 FunctionDecl *SuperConstructorFunctionDecl;
110 FunctionDecl *CurFunctionDef;
113 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
114 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
115 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
116 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
117 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
118 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
119 SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
121 SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
124 SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories;
126 SmallVector<Stmt *, 32> Stmts;
127 SmallVector<int, 8> ObjCBcLabelNo;
129 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
131 llvm::DenseSet<uint64_t> CopyDestroyCache;
134 SmallVector<BlockExpr *, 32> Blocks;
135 SmallVector<int, 32> InnerDeclRefsCount;
136 SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
138 SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
141 llvm::SmallSetVector<ValueDecl *, 8> BlockByCopyDecls;
142 llvm::SmallSetVector<ValueDecl *, 8> BlockByRefDecls;
143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
144 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
145 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
148 llvm::DenseMap<ObjCInterfaceDecl *,
149 llvm::SmallSetVector<ObjCIvarDecl *, 8> > ReferencedIvars;
152 llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>, QualType> GroupRecordType;
157 SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen;
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;
184 void InitializeCommon(ASTContext &context);
187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
190 bool HandleTopLevelDecl(DeclGroupRef D)
override {
191 for (DeclGroupRef::iterator I = D.
begin(), E = D.
end(); I != E; ++I) {
192 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
193 if (!
Class->isThisDeclarationADefinition()) {
194 RewriteForwardClassDecl(D);
198 ObjCInterfacesSeen.push_back(Class);
203 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
204 if (!Proto->isThisDeclarationADefinition()) {
205 RewriteForwardProtocolDecl(D);
210 if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I)) {
215 if (FDecl->isThisDeclarationADefinition() &&
217 !FDecl->isTopLevelDeclInObjCContainer()) {
218 FunctionDefinitionsSeen.push_back(FDecl);
222 HandleTopLevelSingleDecl(*I);
227 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D)
override {
228 for (DeclGroupRef::iterator I = D.
begin(), E = D.
end(); I != E; ++I) {
229 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(*I)) {
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,
243 DiagnosticsEngine &D,
const LangOptions &LOpts,
244 bool silenceMacroWarn,
bool LineInfo);
246 ~RewriteModernObjC()
override {}
248 void HandleTranslationUnit(ASTContext &C)
override;
250 void ReplaceStmt(Stmt *Old, Stmt *
New) {
254 void ReplaceStmtWithRange(Stmt *Old, Stmt *
New, SourceRange SrcRange) {
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);
274 New->printPretty(S,
nullptr, PrintingPolicy(LangOpts));
277 if (!
Rewrite.ReplaceText(SrcRange.getBegin(), Size, SStr)) {
278 ReplacedNodes[Old] =
New;
281 if (SilenceRewriteMacroWarning)
287 void InsertText(SourceLocation Loc, StringRef Str,
288 bool InsertAfter =
true) {
290 if (!
Rewrite.InsertText(Loc, Str, InsertAfter) ||
291 SilenceRewriteMacroWarning)
297 void ReplaceText(SourceLocation Start,
unsigned OrigLength,
300 if (!
Rewrite.ReplaceText(Start, OrigLength, Str) ||
301 SilenceRewriteMacroWarning)
308 void RewriteRecordBody(RecordDecl *RD);
309 void RewriteInclude();
310 void RewriteLineDirective(
const Decl *D);
311 void ConvertSourceLocationToLineDirective(SourceLocation Loc,
312 std::string &LineString);
313 void RewriteForwardClassDecl(DeclGroupRef D);
314 void RewriteForwardClassDecl(
const SmallVectorImpl<Decl *> &DG);
315 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
316 const std::string &typedefString);
317 void RewriteImplementations();
318 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
319 ObjCImplementationDecl *IMD,
320 ObjCCategoryImplDecl *CID);
321 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
322 void RewriteImplementationDecl(Decl *Dcl);
323 void RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
324 ObjCMethodDecl *MDecl, std::string &ResultStr);
325 void RewriteTypeIntoString(QualType T, std::string &ResultStr,
326 const FunctionType *&FPRetType);
327 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
328 ValueDecl *VD,
bool def=
false);
329 void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
330 void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
331 void RewriteForwardProtocolDecl(DeclGroupRef D);
332 void RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG);
333 void RewriteMethodDeclaration(ObjCMethodDecl *Method);
334 void RewriteProperty(ObjCPropertyDecl *prop);
335 void RewriteFunctionDecl(FunctionDecl *FD);
336 void RewriteBlockPointerType(std::string& Str, QualType Type);
337 void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
338 void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
339 void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
340 void RewriteTypeOfDecl(VarDecl *VD);
341 void RewriteObjCQualifiedInterfaceTypes(Expr *E);
343 std::string getIvarAccessString(ObjCIvarDecl *D);
346 Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
347 Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
348 Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
349 Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
350 Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
351 Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
352 Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
353 Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
354 Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
355 Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
356 Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
357 Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
358 Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
359 Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
360 Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
361 Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
362 Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
363 SourceLocation OrigEnd);
364 Stmt *RewriteBreakStmt(BreakStmt *S);
365 Stmt *RewriteContinueStmt(ContinueStmt *S);
366 void RewriteCastExpr(CStyleCastExpr *CE);
367 void RewriteImplicitCastObjCExpr(CastExpr *IE);
370 unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV);
372 void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result);
374 void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result);
376 void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result);
378 QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV);
379 QualType SynthesizeBitfieldGroupStructType(
381 SmallVectorImpl<ObjCIvarDecl *> &IVars);
384 void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
387 void RewriteBlockPointerDecl(NamedDecl *VD);
388 void RewriteByRefVar(VarDecl *VD,
bool firstDecl,
bool lastDecl);
389 Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
390 Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
391 void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
393 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
394 std::string &Result);
396 void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
397 bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag,
398 bool &IsNamedDefinition);
399 void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl,
400 std::string &Result);
402 bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
404 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
405 std::string &Result);
407 void Initialize(ASTContext &context)
override;
411 CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
412 ArrayRef<Expr *> Args,
413 SourceLocation StartLoc=SourceLocation(),
414 SourceLocation EndLoc=SourceLocation());
416 Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
418 SmallVectorImpl<QualType> &ArgTypes,
419 SmallVectorImpl<Expr*> &MsgExprs,
420 ObjCMethodDecl *Method);
422 Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
423 SourceLocation StartLoc=SourceLocation(),
424 SourceLocation EndLoc=SourceLocation());
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);
446 void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
447 std::string &Result);
448 void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
449 std::string &Result);
450 void RewriteClassSetupInitHook(std::string &Result);
452 void RewriteMetaDataIntoBuffer(std::string &Result);
453 void WriteImageInfo(std::string &Result);
454 void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
455 std::string &Result);
456 void RewriteCategorySetupInitHook(std::string &Result);
459 void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
460 std::string &Result);
461 Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
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);
475 Stmt *SynthesizeBlockCall(CallExpr *Exp,
const Expr* BlockExp);
476 void SynthesizeBlockLiterals(SourceLocation FunLocStart,
478 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
479 Stmt *SynthBlockInitExpr(BlockExpr *Exp,
480 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
483 QualType getProtocolType();
484 void WarnAboutReturnGotoStmts(Stmt *S);
485 void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
486 void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
487 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
489 bool IsDeclStmtInForeachHeader(DeclStmt *DS);
490 void CollectBlockDeclRefInfo(BlockExpr *Exp);
491 void GetBlockDeclRefExprs(Stmt *S);
492 void GetInnerBlockDeclRefExprs(Stmt *S,
493 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
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)) {
507 const auto *BPT =
T->
castAs<BlockPointerType>();
514 bool convertObjCTypeToCStyleType(QualType &T);
516 bool needToScanForQualifiers(QualType T);
517 QualType getSuperStructType();
518 QualType getConstantStringStructType();
519 QualType convertFunctionTypeOfBlocks(
const FunctionType *FT);
521 void convertToUnqualifiedObjCType(QualType &T) {
523 bool isConst =
T.isConstQualified();
531 if (
const ObjCObjectPointerType * OBJPT =
533 const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
534 T = QualType(IFaceT, 0);
541 bool isObjCType(QualType T) {
551 if (
const PointerType *PT = OCT->
getAs<PointerType>()) {
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++) {
573 QualType getSimpleFunctionType(QualType result,
574 ArrayRef<QualType> args,
575 bool variadic =
false) {
578 FunctionProtoType::ExtProtoInfo fpi;
584 CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
585 CastKind Kind, Expr *E) {
587 return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue, Kind, E,
nullptr,
588 FPOptionsOverride(), TInfo,
589 SourceLocation(), SourceLocation());
592 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
593 const IdentifierInfo *II = &Context->
Idents.get(
"load");
594 Selector LoadSel = Context->
Selectors.getSelector(0, &II);
598 StringLiteral *getStringLiteral(StringRef Str) {
600 Context->
CharTy, llvm::APInt(32, Str.size() + 1),
nullptr,
601 ArraySizeModifier::Normal, 0);
602 return StringLiteral::Create(*Context, Str, StringLiteralKind::Ordinary,
603 false, StrType, SourceLocation());
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) {
622 const PointerType *PT = funcType->
getAs<PointerType>();
623 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
624 RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
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)");
654 "rewriting block literal declared in global scope is not implemented");
658 "rewriter doesn't support user-specified control flow semantics "
659 "for @try/@finally (code may not execute properly)");
663 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
665 bool SilenceRewriteMacroWarning,
bool LineInfo) {
666 return std::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
667 LOpts, SilenceRewriteMacroWarning,
671void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
673 SM = &Context->getSourceManager();
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) {
723 Loc =
SM->getExpansionLoc(Loc);
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()) {
750 SourceLocation StartLoc = IFace->getBeginLoc();
754 StartLoc == (*DI)->getBeginLoc())
760 }
while (DI != DIEnd);
761 RewriteForwardClassDecl(DG);
766 ObjCInterfacesSeen.push_back(IFace);
773 if (!Proto->isThisDeclarationADefinition()) {
775 SourceLocation StartLoc = Proto->getBeginLoc();
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() {
805 SourceLocation LocStart =
SM->getLocForStartOfFile(MainFileID);
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)) {
821 SourceLocation ImportLoc =
822 LocStart.getLocWithOffset(BufPtr-MainBufStart);
823 ReplaceText(ImportLoc, ImportLen,
"include");
832 Result +=
"OBJC_IVAR_$_";
839RewriteModernObjC::getIvarAccessString(
ObjCIvarDecl *D) {
843 std::string IvarOffsetName;
845 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
847 WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
849 std::string S =
"(*(";
852 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
862 CDecl = CatDecl->getClassInterface();
863 std::string RecName = std::string(CDecl->getName());
866 SourceLocation(), SourceLocation(),
867 &Context->Idents.get(RecName));
869 Context->getPointerType(Context->getCanonicalTagType(RD));
870 unsigned UnsignedIntSize =
871 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
873 llvm::APInt(UnsignedIntSize, 0),
874 Context->UnsignedIntTy, SourceLocation());
875 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
886 IvarT = Context->getDecltypeType(ME, ME->
getType());
889 convertObjCTypeToCStyleType(IvarT);
890 QualType castT = Context->getPointerType(IvarT);
891 std::string TypeString(castT.
getAsString(Context->getPrintingPolicy()));
896 S +=
"((char *)self + ";
920 static bool objcGetPropertyDefined =
false;
921 static bool objcSetPropertyDefined =
false;
922 SourceLocation startGetterSetterLoc;
926 InsertText(startLoc,
"// ");
927 const char *startBuf =
SM->getCharacterData(startLoc);
928 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
929 const char *semiBuf = strchr(startBuf,
';');
930 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
931 startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
941 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
944 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
945 bool GenGetProperty =
950 if (GenGetProperty && !objcGetPropertyDefined) {
951 objcGetPropertyDefined =
true;
953 Getr =
"\nextern \"C\" __declspec(dllimport) "
954 "id objc_getProperty(id, SEL, long, bool);\n";
961 if (GenGetProperty) {
974 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
976 std::string ParamStr =
977 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
980 if (FT->isVariadic()) {
981 if (FT->getNumParams())
990 Getr +=
"return (_TYPE)";
991 Getr +=
"objc_getProperty(self, _cmd, ";
992 RewriteIvarOffsetComputation(OID, Getr);
996 Getr +=
"return " + getIvarAccessString(OID);
998 InsertText(startGetterSetterLoc, Getr);
1002 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1009 if (GenSetProperty && !objcSetPropertyDefined) {
1010 objcSetPropertyDefined =
true;
1012 Setr =
"\nextern \"C\" __declspec(dllimport) "
1013 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1021 if (GenSetProperty) {
1022 Setr +=
"objc_setProperty (self, _cmd, ";
1023 RewriteIvarOffsetComputation(OID, Setr);
1037 Setr += getIvarAccessString(OID) +
" = ";
1041 InsertText(startGetterSetterLoc, Setr);
1045 std::string &typedefString) {
1046 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1048 typedefString +=
"\n";
1049 typedefString +=
"#define _REWRITER_typedef_";
1051 typedefString +=
"\n";
1052 typedefString +=
"typedef struct objc_object ";
1055 typedefString +=
";\ntypedef struct {} _objc_exc_";
1057 typedefString +=
";\n#endif\n";
1060void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1061 const std::string &typedefString) {
1062 SourceLocation startLoc = ClassDecl->
getBeginLoc();
1063 const char *startBuf =
SM->getCharacterData(startLoc);
1064 const char *semiPtr = strchr(startBuf,
';');
1066 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1069void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1070 std::string typedefString;
1073 if (I == D.
begin()) {
1077 typedefString +=
"// @class ";
1079 typedefString +=
";";
1081 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1084 HandleTopLevelSingleDecl(*I);
1090void RewriteModernObjC::RewriteForwardClassDecl(
1092 std::string typedefString;
1093 for (
unsigned i = 0; i < D.size(); i++) {
1096 typedefString +=
"// @class ";
1098 typedefString +=
";";
1100 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1105void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1108 if (Method->isImplicit())
1110 SourceLocation LocStart = Method->getBeginLoc();
1111 SourceLocation LocEnd = Method->getEndLoc();
1113 if (
SM->getExpansionLineNumber(LocEnd) >
1114 SM->getExpansionLineNumber(LocStart)) {
1115 InsertText(LocStart,
"#if 0\n");
1116 ReplaceText(LocEnd, 1,
";\n#endif\n");
1118 InsertText(LocStart,
"// ");
1123 SourceLocation Loc = prop->
getAtLoc();
1125 ReplaceText(Loc, 0,
"// ");
1134 ReplaceText(LocStart, 1,
"/** ");
1138 ReplaceText(LocStart, 0,
"// ");
1145 RewriteMethodDeclaration(I);
1147 RewriteMethodDeclaration(I);
1151 strlen(
"@end"),
"/* @end */\n");
1159 ReplaceText(LocStart, 0,
"// ");
1162 RewriteMethodDeclaration(I);
1164 RewriteMethodDeclaration(I);
1170 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1173 const char *startBuf =
SM->getCharacterData(LocStart);
1174 const char *endBuf =
SM->getCharacterData(LocEnd);
1175 for (
const char *p = startBuf; p < endBuf; p++) {
1176 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1177 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
1178 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1181 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1182 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
1183 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1189void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1190 SourceLocation LocStart = (*D.
begin())->getBeginLoc();
1191 if (LocStart.isInvalid())
1192 llvm_unreachable(
"Invalid SourceLocation");
1194 ReplaceText(LocStart, 0,
"// ");
1199 SourceLocation LocStart = DG[0]->getBeginLoc();
1200 if (LocStart.isInvalid())
1201 llvm_unreachable(
"Invalid SourceLocation");
1203 ReplaceText(LocStart, 0,
"// ");
1206void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1208 if (T->isObjCQualifiedIdType())
1210 else if (T->isFunctionPointerType() ||
1211 T->isBlockPointerType()) {
1216 if (
const PointerType* PT = retType->
getAs<PointerType>())
1217 PointeeTy = PT->getPointeeType();
1226 ResultStr += T.getAsString(Context->getPrintingPolicy());
1231 std::string &ResultStr) {
1234 ResultStr +=
"\nstatic ";
1235 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1239 std::string NameStr;
1257 int len = selString.size();
1258 for (
int i = 0; i < len; i++)
1259 if (selString[i] ==
':')
1261 NameStr += selString;
1264 MethodInternalNames[OMD] = NameStr;
1265 ResultStr += NameStr;
1272 QualType selfTy = Context->getObjCInterfaceType(IDecl);
1273 selfTy = Context->getPointerType(selfTy);
1274 if (!LangOpts.MicrosoftExt) {
1276 ResultStr +=
"struct ";
1283 ResultStr += Context->getObjCClassType().getAsString(
1284 Context->getPrintingPolicy());
1286 ResultStr +=
" self, ";
1287 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
1288 ResultStr +=
" _cmd";
1291 for (
const auto *PDecl : OMD->
parameters()) {
1293 if (PDecl->getType()->isObjCQualifiedIdType()) {
1300 (void)convertBlockPointerToFunctionPointer(QT);
1306 ResultStr +=
", ...";
1315 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1316 if (i) ResultStr +=
", ";
1317 std::string ParamStr =
1318 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
1319 ResultStr += ParamStr;
1321 if (FT->isVariadic()) {
1322 if (FT->getNumParams())
1333void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1336 assert((IMD || CID) &&
"Unknown implementation type");
1353 std::string ResultStr;
1358 const char *startBuf =
SM->getCharacterData(LocStart);
1359 const char *endBuf =
SM->getCharacterData(LocEnd);
1360 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1366 std::string ResultStr;
1371 const char *startBuf =
SM->getCharacterData(LocStart);
1372 const char *endBuf =
SM->getCharacterData(LocEnd);
1373 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1376 RewritePropertyImplDecl(I, IMD, CID);
1383 if (ObjCSynthesizedStructs.count(ClassDecl))
1387 while (SuperClass) {
1388 RewriteInterfaceDecl(SuperClass);
1391 std::string ResultStr;
1394 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1395 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1397 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1404 RewriteMethodDeclaration(I);
1406 RewriteMethodDeclaration(I);
1428 DisableReplaceStmtScope S(*
this);
1439 for (
unsigned i = 0; i < numArgs; i++) {
1443 Arg =
cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1444 Args.push_back(Arg);
1497 Stmt *Replacement = SynthMessageExpr(NewMsg);
1498 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1515 DisableReplaceStmtScope S(*
this);
1523 for (
unsigned i = 0; i < numArgs; i++) {
1527 Arg =
cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1528 Args.push_back(Arg);
1580 Stmt *Replacement = SynthMessageExpr(NewMsg);
1581 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1594void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1595 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1596 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1598 buf +=
"((id)l_collection,\n\t\t";
1599 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1601 buf +=
"&enumState, "
1602 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1615 buf =
"goto __break_label_";
1616 buf += utostr(ObjCBcLabelNo.back());
1617 ReplaceText(startLoc, strlen(
"break"), buf);
1622void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1624 std::string &LineString) {
1625 if (Loc.isFileID() && GenerateLineInfo) {
1626 LineString +=
"\n#line ";
1628 LineString += utostr(PLoc.
getLine());
1629 LineString +=
" \"";
1631 LineString +=
"\"\n";
1645 buf =
"goto __continue_label_";
1646 buf += utostr(ObjCBcLabelNo.back());
1647 ReplaceText(startLoc, strlen(
"continue"), buf);
1685 SourceLocation OrigEnd) {
1686 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1688 "ObjCForCollectionStmt Statement stack mismatch");
1689 assert(!ObjCBcLabelNo.empty() &&
1690 "ObjCForCollectionStmt - Label No stack empty");
1693 const char *startBuf =
SM->getCharacterData(startLoc);
1694 StringRef elementName;
1695 std::string elementTypeAsString;
1698 SourceLocation ForEachLoc = S->
getForLoc();
1699 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1708 elementTypeAsString =
"id";
1710 elementTypeAsString = ElementType.
getAsString(Context->getPrintingPolicy());
1711 buf += elementTypeAsString;
1724 elementTypeAsString =
"id";
1730 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1732 buf +=
"id __rw_items[16];\n\t";
1734 buf +=
"id l_collection = (id)";
1736 const char *startCollectionBuf = startBuf;
1737 startCollectionBuf += 3;
1738 startCollectionBuf = strchr(startCollectionBuf,
'(');
1739 startCollectionBuf++;
1741 while (*startCollectionBuf !=
' ' ||
1742 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1743 (*(startCollectionBuf+3) !=
' ' &&
1744 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1745 startCollectionBuf++;
1746 startCollectionBuf += 3;
1749 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1752 const char *rparenBuf =
SM->getCharacterData(rightParenLoc);
1753 SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
1767 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1768 SynthCountByEnumWithState(buf);
1778 buf +=
"if (limit) {\n\t";
1779 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1780 buf +=
"do {\n\t\t";
1781 buf +=
"unsigned long counter = 0;\n\t\t";
1782 buf +=
"do {\n\t\t\t";
1783 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1784 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1787 buf += elementTypeAsString;
1788 buf +=
")enumState.itemsPtr[counter++];";
1790 ReplaceText(lparenLoc, 1, buf);
1804 buf +=
"__continue_label_";
1805 buf += utostr(ObjCBcLabelNo.back());
1808 buf +=
"} while (counter < limit);\n\t";
1809 buf +=
"} while ((limit = ";
1810 SynthCountByEnumWithState(buf);
1814 buf += elementTypeAsString;
1816 buf +=
"__break_label_";
1817 buf += utostr(ObjCBcLabelNo.back());
1820 buf +=
"else\n\t\t";
1823 buf += elementTypeAsString;
1830 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
1831 InsertText(endBodyLoc, buf);
1840 const char *stmtBuf =
SM->getCharacterData(OrigEnd);
1841 const char *semiBuf = strchr(stmtBuf,
';');
1842 assert(semiBuf &&
"Can't find ';'");
1843 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
1844 InsertText(endBodyLoc, buf);
1847 ObjCBcLabelNo.pop_back();
1851static void Write_RethrowObject(std::string &buf) {
1852 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1853 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1854 buf +=
"\tid rethrow;\n";
1855 buf +=
"\t} _fin_force_rethow(_rethrow);";
1867 const char *startBuf =
SM->getCharacterData(startLoc);
1869 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1873 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1874 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1876 const char *lparenBuf = startBuf;
1877 while (*lparenBuf !=
'(') lparenBuf++;
1878 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1880 buf =
"; objc_sync_enter(_sync_obj);\n";
1881 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1882 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1883 buf +=
"\n\tid sync_exit;";
1884 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1890 const char *RParenExprLocBuf =
SM->getCharacterData(RParenExprLoc);
1891 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1892 RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
1895 const char *LBraceLocBuf =
SM->getCharacterData(LBranceLoc);
1896 assert (*LBraceLocBuf ==
'{');
1897 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->getCharacterData(RParenExprLoc) + 1), buf);
1900 assert((*
SM->getCharacterData(startRBraceLoc) ==
'}') &&
1901 "bogus @synchronized block");
1903 buf =
"} catch (id e) {_rethrow = e;}\n";
1904 Write_RethrowObject(buf);
1908 ReplaceText(startRBraceLoc, 1, buf);
1913void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1918 WarnAboutReturnGotoStmts(SubStmt);
1922 TryFinallyContainsReturnDiag);
1927 SourceLocation startLoc = S->
getAtLoc();
1928 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1930 "{ __AtAutoreleasePool __autoreleasepool; ");
1940 ConvertSourceLocationToLineDirective(TryLocation, buf);
1944 buf +=
"{ id volatile _rethrow = 0;\n";
1946 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1951 const char *startBuf =
SM->getCharacterData(startLoc);
1953 assert((*startBuf ==
'@') &&
"bogus @try location");
1955 ReplaceText(startLoc, 1, buf);
1958 ReplaceText(startLoc, 1,
"");
1961 VarDecl *catchDecl = Catch->getCatchParamDecl();
1963 startLoc = Catch->getBeginLoc();
1964 bool AtRemoved =
false;
1973 ConvertSourceLocationToLineDirective(Catch->getBeginLoc(), Result);
1975 startBuf =
SM->getCharacterData(startLoc);
1976 assert((*startBuf ==
'@') &&
"bogus @catch location");
1977 SourceLocation rParenLoc = Catch->getRParenLoc();
1978 const char *rParenBuf =
SM->getCharacterData(rParenLoc);
1984 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1994 SourceLocation lBraceLoc = Catch->getCatchBody()->getBeginLoc();
1995 ReplaceText(lBraceLoc, 1, Result);
2002 ReplaceText(startLoc, 1,
"");
2007 SourceLocation FinallyLoc = finalStmt->
getBeginLoc();
2010 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2011 buf +=
"catch (id e) {_rethrow = e;}\n";
2015 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2016 buf +=
"catch (id e) {_rethrow = e;}\n";
2019 SourceLocation startFinalLoc = finalStmt->
getBeginLoc();
2020 ReplaceText(startFinalLoc, 8, buf);
2022 SourceLocation startFinalBodyLoc = body->
getBeginLoc();
2024 Write_RethrowObject(buf);
2025 ReplaceText(startFinalBodyLoc, 1, buf);
2027 SourceLocation endFinalBodyLoc = body->
getEndLoc();
2028 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2042 const char *startBuf =
SM->getCharacterData(startLoc);
2044 assert((*startBuf ==
'@') &&
"bogus @throw location");
2049 buf =
"objc_exception_throw(";
2054 const char *wBuf = strchr(startBuf,
'w');
2055 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2056 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2059 const char *endBuf =
SM->getCharacterData(endLoc);
2060 const char *semiBuf = strchr(endBuf,
';');
2061 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2062 SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
2064 ReplaceText(semiLoc, 1,
");");
2070 std::string StrEncoding;
2071 Context->getObjCEncodingForType(Exp->
getEncodedType(), StrEncoding);
2072 Expr *Replacement = getStringLiteral(StrEncoding);
2073 ReplaceStmt(Exp, Replacement);
2081 if (!SelGetUidFunctionDecl)
2082 SynthSelGetUidFunctionDecl();
2083 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2087 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2089 ReplaceStmt(Exp, SelExp);
2095RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2097 SourceLocation StartLoc,
2098 SourceLocation EndLoc) {
2107 QualType pToFunc = Context->getPointerType(msgSendType);
2119static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2120 const char *&startRef,
const char *&endRef) {
2121 while (startBuf < endBuf) {
2122 if (*startBuf ==
'<')
2123 startRef = startBuf;
2124 if (*startBuf ==
'>') {
2125 if (startRef && *startRef ==
'<') {
2136static void scanToNextArgument(
const char *&argRef) {
2138 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2141 else if (*argRef ==
'>')
2145 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2148bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2149 if (T->isObjCQualifiedIdType())
2151 if (
const PointerType *PT = T->getAs<PointerType>()) {
2152 if (PT->getPointeeType()->isObjCQualifiedIdType())
2155 if (T->isObjCObjectPointerType()) {
2156 T = T->getPointeeType();
2157 return T->isObjCQualifiedInterfaceType();
2159 if (T->isArrayType()) {
2160 QualType ElemTy = Context->getBaseElementType(T);
2161 return needToScanForQualifiers(ElemTy);
2166void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2168 if (needToScanForQualifiers(Type)) {
2169 SourceLocation Loc, EndLoc;
2172 Loc = ECE->getLParenLoc();
2173 EndLoc = ECE->getRParenLoc();
2179 if (Loc.isInvalid() || EndLoc.isInvalid())
2182 const char *startBuf =
SM->getCharacterData(Loc);
2183 const char *endBuf =
SM->getCharacterData(EndLoc);
2184 const char *startRef =
nullptr, *endRef =
nullptr;
2185 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2187 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
2188 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
2190 InsertText(LessLoc,
"/*");
2191 InsertText(GreaterLoc,
"*/");
2196void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2200 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2204 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2209 assert(funcType &&
"missing function type");
2210 proto = dyn_cast<FunctionProtoType>(funcType);
2215 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2220 Loc = TD->getLocation();
2221 Type = TD->getUnderlyingType();
2226 if (needToScanForQualifiers(Type)) {
2229 const char *endBuf =
SM->getCharacterData(Loc);
2230 const char *startBuf = endBuf;
2231 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2233 const char *startRef =
nullptr, *endRef =
nullptr;
2234 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2236 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
2237 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
2239 InsertText(LessLoc,
"/*");
2240 InsertText(GreaterLoc,
"*/");
2246 const char *startBuf =
SM->getCharacterData(Loc);
2247 const char *startFuncBuf = startBuf;
2252 const char *endBuf = startBuf;
2254 scanToNextArgument(endBuf);
2255 const char *startRef =
nullptr, *endRef =
nullptr;
2256 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2258 SourceLocation LessLoc =
2259 Loc.getLocWithOffset(startRef-startFuncBuf);
2260 SourceLocation GreaterLoc =
2261 Loc.getLocWithOffset(endRef-startFuncBuf+1);
2263 InsertText(LessLoc,
"/*");
2264 InsertText(GreaterLoc,
"*/");
2266 startBuf = ++endBuf;
2271 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2278void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2280 const Type* TypePtr = QT->
getAs<Type>();
2286 TypePtr = QT->
getAs<Type>();
2290 std::string TypeAsString(QT.
getAsString(Context->getPrintingPolicy()));
2292 const char *startBuf =
SM->getCharacterData(DeclLoc);
2295 TypeAsString +=
" " + Name +
" = ";
2297 SourceLocation startLoc;
2299 startLoc = ECE->getLParenLoc();
2302 startLoc =
SM->getExpansionLoc(startLoc);
2303 const char *endBuf =
SM->getCharacterData(startLoc);
2304 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2308 X =
SM->getExpansionLoc(
X);
2309 const char *endBuf =
SM->getCharacterData(
X);
2310 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2315void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2316 IdentifierInfo *SelGetUidIdent = &Context->Idents.get(
"sel_registerName");
2318 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2320 getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
2324 SelGetUidIdent, getFuncType,
2328void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2331 FD->
getName() ==
"sel_registerName") {
2332 SelGetUidFunctionDecl = FD;
2335 RewriteObjCQualifiedInterfaceTypes(FD);
2338void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2339 std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
2340 const char *argPtr = TypeString.c_str();
2341 if (!strchr(argPtr,
'^')) {
2346 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2352void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2355 std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
2356 const char *argPtr = TypeString.c_str();
2381void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2387 QualType Type = proto->getReturnType();
2388 std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
2392 unsigned numArgs = proto->getNumParams();
2393 for (
unsigned i = 0; i < numArgs; i++) {
2394 QualType ArgType = proto->getParamType(i);
2395 RewriteBlockPointerType(FdStr, ArgType);
2400 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2404 InsertText(FunLocStart, FdStr);
2408void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2409 if (SuperConstructorFunctionDecl)
2411 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"__rw_objc_super");
2413 QualType argT = Context->getObjCIdType();
2414 assert(!argT.
isNull() &&
"Can't find 'id' type");
2415 ArgTys.push_back(argT);
2416 ArgTys.push_back(argT);
2417 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2422 msgSendIdent, msgSendType,
2427void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2428 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend");
2430 QualType argT = Context->getObjCIdType();
2431 assert(!argT.
isNull() &&
"Can't find 'id' type");
2432 ArgTys.push_back(argT);
2433 argT = Context->getObjCSelType();
2434 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2435 ArgTys.push_back(argT);
2436 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2441 msgSendIdent, msgSendType,
nullptr,
2446void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2447 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSendSuper");
2449 ArgTys.push_back(Context->VoidTy);
2450 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2455 msgSendIdent, msgSendType,
2460void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2461 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_stret");
2463 QualType argT = Context->getObjCIdType();
2464 assert(!argT.
isNull() &&
"Can't find 'id' type");
2465 ArgTys.push_back(argT);
2466 argT = Context->getObjCSelType();
2467 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2468 ArgTys.push_back(argT);
2469 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2474 msgSendIdent, msgSendType,
2480void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2482 &Context->Idents.get(
"objc_msgSendSuper_stret");
2484 ArgTys.push_back(Context->VoidTy);
2485 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2491 msgSendType,
nullptr,
2496void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2497 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_fpret");
2499 QualType argT = Context->getObjCIdType();
2500 assert(!argT.
isNull() &&
"Can't find 'id' type");
2501 ArgTys.push_back(argT);
2502 argT = Context->getObjCSelType();
2503 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2504 ArgTys.push_back(argT);
2505 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
2510 msgSendIdent, msgSendType,
2515void RewriteModernObjC::SynthGetClassFunctionDecl() {
2516 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getClass");
2518 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2519 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2524 getClassIdent, getClassType,
2529void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2531 &Context->Idents.get(
"class_getSuperclass");
2533 ArgTys.push_back(Context->getObjCClassType());
2534 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2540 getClassType,
nullptr,
2545void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2546 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getMetaClass");
2548 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2549 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2554 getClassIdent, getClassType,
2559 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2560 QualType strType = getConstantStringStructType();
2562 std::string S =
"__NSConstantStringImpl_";
2564 std::string tmpName = InFileName;
2566 for (i=0; i < tmpName.length(); i++) {
2567 char c = tmpName.at(i);
2574 S += utostr(NumObjCStringLiterals++);
2576 Preamble +=
"static __NSConstantStringImpl " + S;
2577 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2580 std::string prettyBufS;
2581 llvm::raw_string_ostream prettyBuf(prettyBufS);
2588 SourceLocation(), &Context->Idents.get(S),
2593 const_cast<ASTContext &
>(*Context), DRE, UO_AddrOf,
2598 CK_CPointerToObjCPointerCast, Unop);
2599 ReplaceStmt(Exp,
cast);
2606 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
2609 llvm::APInt(IntSize, Exp->
getValue()),
2611 CastExpr *
cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
2612 CK_BitCast, FlagExp);
2615 ReplaceStmt(Exp, PE);
2621 if (!SelGetUidFunctionDecl)
2622 SynthSelGetUidFunctionDecl();
2624 if (!MsgSendFunctionDecl)
2625 SynthMsgSendFunctionDecl();
2626 if (!GetClassFunctionDecl)
2627 SynthGetClassFunctionDecl();
2631 SourceLocation EndLoc = Exp->
getEndLoc();
2642 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2643 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2645 MsgExprs.push_back(Cls);
2652 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2653 SelExprs, StartLoc, EndLoc);
2654 MsgExprs.push_back(SelExp);
2663 CK = CK_IntegralToBoolean;
2664 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2666 MsgExprs.push_back(subExpr);
2669 ArgTypes.push_back(Context->getObjCClassType());
2670 ArgTypes.push_back(Context->getObjCSelType());
2671 for (
const auto PI : BoxingMethod->
parameters())
2672 ArgTypes.push_back(PI->getType());
2680 *Context, MsgSendFlavor,
false, msgSendType,
VK_LValue, SourceLocation());
2683 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2687 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2688 castType = Context->getPointerType(castType);
2689 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2698 ReplaceStmt(Exp, CE);
2704 if (!SelGetUidFunctionDecl)
2705 SynthSelGetUidFunctionDecl();
2707 if (!MsgSendFunctionDecl)
2708 SynthMsgSendFunctionDecl();
2709 if (!GetClassFunctionDecl)
2710 SynthGetClassFunctionDecl();
2714 SourceLocation EndLoc = Exp->
getEndLoc();
2719 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2720 std::string NSArrayFName(
"__NSContainer_literal");
2721 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2723 *Context, NSArrayFD,
false, NSArrayFType,
VK_PRValue, SourceLocation());
2727 unsigned UnsignedIntSize =
2728 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2730 llvm::APInt(UnsignedIntSize, NumElements),
2731 Context->UnsignedIntTy, SourceLocation());
2732 InitExprs.push_back(count);
2733 for (
unsigned i = 0; i < NumElements; i++)
2735 Expr *NSArrayCallExpr =
2741 &Context->Idents.get(
"arr"),
2742 Context->getPointerType(Context->VoidPtrTy),
2748 QualType ConstIdT = Context->getObjCIdType().withConst();
2750 NoTypeInfoCStyleCastExpr(Context,
2751 Context->getPointerType(ConstIdT),
2765 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2766 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2768 MsgExprs.push_back(Cls);
2776 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2777 SelExprs, StartLoc, EndLoc);
2778 MsgExprs.push_back(SelExp);
2781 MsgExprs.push_back(ArrayLiteralObjects);
2785 llvm::APInt(UnsignedIntSize, NumElements),
2786 Context->UnsignedIntTy, SourceLocation());
2787 MsgExprs.push_back(cnt);
2790 ArgTypes.push_back(Context->getObjCClassType());
2791 ArgTypes.push_back(Context->getObjCSelType());
2792 for (
const auto *PI : ArrayMethod->
parameters())
2793 ArgTypes.push_back(PI->getType());
2801 *Context, MsgSendFlavor,
false, msgSendType,
VK_LValue, SourceLocation());
2804 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2808 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2809 castType = Context->getPointerType(castType);
2810 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2819 ReplaceStmt(Exp, CE);
2825 if (!SelGetUidFunctionDecl)
2826 SynthSelGetUidFunctionDecl();
2828 if (!MsgSendFunctionDecl)
2829 SynthMsgSendFunctionDecl();
2830 if (!GetClassFunctionDecl)
2831 SynthGetClassFunctionDecl();
2835 SourceLocation EndLoc = Exp->
getEndLoc();
2840 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2841 std::string NSDictFName(
"__NSContainer_literal");
2842 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2844 *Context, NSDictFD,
false, NSDictFType,
VK_PRValue, SourceLocation());
2850 unsigned UnsignedIntSize =
2851 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2853 llvm::APInt(UnsignedIntSize, NumElements),
2854 Context->UnsignedIntTy, SourceLocation());
2855 KeyExprs.push_back(count);
2856 ValueExprs.push_back(count);
2857 for (
unsigned i = 0; i < NumElements; i++) {
2859 KeyExprs.push_back(Element.
Key);
2860 ValueExprs.push_back(Element.
Value);
2864 Expr *NSValueCallExpr =
2870 &Context->Idents.get(
"arr"),
2871 Context->getPointerType(Context->VoidPtrTy),
2877 QualType ConstIdT = Context->getObjCIdType().withConst();
2879 NoTypeInfoCStyleCastExpr(Context,
2880 Context->getPointerType(ConstIdT),
2882 DictLiteralValueME);
2884 Expr *NSKeyCallExpr =
2893 NoTypeInfoCStyleCastExpr(Context,
2894 Context->getPointerType(ConstIdT),
2908 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2909 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2911 MsgExprs.push_back(Cls);
2918 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2919 SelExprs, StartLoc, EndLoc);
2920 MsgExprs.push_back(SelExp);
2923 MsgExprs.push_back(DictValueObjects);
2926 MsgExprs.push_back(DictKeyObjects);
2930 llvm::APInt(UnsignedIntSize, NumElements),
2931 Context->UnsignedIntTy, SourceLocation());
2932 MsgExprs.push_back(cnt);
2935 ArgTypes.push_back(Context->getObjCClassType());
2936 ArgTypes.push_back(Context->getObjCSelType());
2937 for (
const auto *PI : DictMethod->
parameters()) {
2939 if (
const PointerType* PT = T->getAs<PointerType>()) {
2940 QualType PointeeTy = PT->getPointeeType();
2941 convertToUnqualifiedObjCType(PointeeTy);
2942 T = Context->getPointerType(PointeeTy);
2944 ArgTypes.push_back(T);
2953 *Context, MsgSendFlavor,
false, msgSendType,
VK_LValue, SourceLocation());
2956 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2960 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2961 castType = Context->getPointerType(castType);
2962 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2971 ReplaceStmt(Exp, CE);
2978QualType RewriteModernObjC::getSuperStructType() {
2979 if (!SuperStructDecl) {
2982 SourceLocation(), &Context->Idents.get(
"__rw_objc_super"));
2986 FieldTypes[0] = Context->getObjCIdType();
2988 FieldTypes[1] = Context->getObjCIdType();
2991 for (
unsigned i = 0; i < 2; ++i) {
2994 SourceLocation(),
nullptr,
2995 FieldTypes[i],
nullptr,
3003 return Context->getCanonicalTagType(SuperStructDecl);
3006QualType RewriteModernObjC::getConstantStringStructType() {
3007 if (!ConstantStringDecl) {
3010 SourceLocation(), &Context->Idents.get(
"__NSConstantStringImpl"));
3014 FieldTypes[0] = Context->getObjCIdType();
3016 FieldTypes[1] = Context->IntTy;
3018 FieldTypes[2] = Context->getPointerType(Context->CharTy);
3020 FieldTypes[3] = Context->LongTy;
3023 for (
unsigned i = 0; i < 4; ++i) {
3027 SourceLocation(),
nullptr,
3028 FieldTypes[i],
nullptr,
3036 return Context->getCanonicalTagType(ConstantStringDecl);
3042static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3048 if (!LSD->getRBraceLoc().isValid())
3049 return LSD->getExternLoc();
3052 R.RewriteBlockLiteralFunctionDecl(FD);
3056void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3060 if (Location.isFileID() && GenerateLineInfo) {
3061 std::string LineString(
"\n#line ");
3063 LineString += utostr(PLoc.
getLine());
3064 LineString +=
" \"";
3068 else LineString +=
"\"\n";
3071 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3076 if (!LSD->getRBraceLoc().isValid())
3077 Location = LSD->getExternLoc();
3080 InsertText(Location, LineString);
3094Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3100 QualType FuncType = getSimpleFunctionType(
3101 returnType, ArgTypes, Method ? Method->isVariadic() :
false);
3102 QualType castType = Context->getPointerType(FuncType);
3105 static unsigned stretCount=0;
3106 std::string
name =
"__Stret";
name += utostr(stretCount);
3108 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3109 str +=
"namespace {\n";
3110 str +=
"struct "; str +=
name;
3113 str +=
"(id receiver, SEL sel";
3114 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3115 std::string ArgName =
"arg"; ArgName += utostr(i);
3116 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
3117 str +=
", "; str += ArgName;
3120 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3121 std::string ArgName =
"arg"; ArgName += utostr(i);
3122 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3123 Context->getPrintingPolicy());
3124 str +=
", "; str += ArgName;
3128 str +=
"\t unsigned size = sizeof(";
3129 str += returnType.
getAsString(Context->getPrintingPolicy()); str +=
");\n";
3131 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3133 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3134 str +=
")(void *)objc_msgSend)(receiver, sel";
3135 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3136 str +=
", arg"; str += utostr(i);
3139 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3140 str +=
", arg"; str += utostr(i);
3144 str +=
"\t else if (receiver == 0)\n";
3145 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3148 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3149 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3150 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3151 str +=
", arg"; str += utostr(i);
3154 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3155 str +=
", arg"; str += utostr(i);
3160 str +=
"\t"; str += returnType.
getAsString(Context->getPrintingPolicy());
3162 str +=
"};\n};\n\n";
3163 SourceLocation FunLocStart;
3165 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3167 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3171 InsertText(FunLocStart, str);
3178 ID, FuncType,
nullptr,
SC_Extern,
false,
false);
3187 &Context->Idents.get(
"s"),
3188 returnType,
nullptr,
3198 SourceLocation StartLoc,
3199 SourceLocation EndLoc) {
3200 if (!SelGetUidFunctionDecl)
3201 SynthSelGetUidFunctionDecl();
3202 if (!MsgSendFunctionDecl)
3203 SynthMsgSendFunctionDecl();
3204 if (!MsgSendSuperFunctionDecl)
3205 SynthMsgSendSuperFunctionDecl();
3206 if (!MsgSendStretFunctionDecl)
3207 SynthMsgSendStretFunctionDecl();
3208 if (!MsgSendSuperStretFunctionDecl)
3209 SynthMsgSendSuperStretFunctionDecl();
3210 if (!MsgSendFpretFunctionDecl)
3211 SynthMsgSendFpretFunctionDecl();
3212 if (!GetClassFunctionDecl)
3213 SynthGetClassFunctionDecl();
3214 if (!GetSuperClassFunctionDecl)
3215 SynthGetSuperClassFunctionDecl();
3216 if (!GetMetaClassFunctionDecl)
3217 SynthGetMetaClassFunctionDecl();
3224 QualType resultType = mDecl->getReturnType();
3226 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3228 MsgSendFlavor = MsgSendFpretFunctionDecl;
3235 MsgSendFlavor = MsgSendSuperFunctionDecl;
3236 if (MsgSendStretFlavor)
3237 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3238 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3245 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3246 Context, Context->getObjCIdType(), CK_BitCast,
3249 SourceLocation())));
3255 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3256 ClsExprs, StartLoc, EndLoc);
3258 ClsExprs.push_back(Cls);
3259 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3264 InitExprs.push_back(
3265 NoTypeInfoCStyleCastExpr(Context,
3266 Context->getObjCIdType(),
3269 QualType superType = getSuperStructType();
3272 if (LangOpts.MicrosoftExt) {
3273 SynthSuperConstructorFunctionDecl();
3276 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3288 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3291 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3292 Context->getPointerType(superType),
3293 CK_BitCast, SuperRep);
3297 new (Context)
InitListExpr(*Context, SourceLocation(), InitExprs,
3300 = Context->getTrivialTypeSourceInfo(superType);
3306 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3310 MsgExprs.push_back(SuperRep);
3319 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3320 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3322 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3323 Context->getObjCIdType(),
3325 MsgExprs.push_back(ArgExpr);
3330 MsgSendFlavor = MsgSendSuperFunctionDecl;
3331 if (MsgSendStretFlavor)
3332 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3333 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3337 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3338 Context, Context->getObjCIdType(), CK_BitCast,
3341 SourceLocation())));
3347 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3350 ClsExprs.push_back(Cls);
3351 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3356 InitExprs.push_back(
3358 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3361 QualType superType = getSuperStructType();
3364 if (LangOpts.MicrosoftExt) {
3365 SynthSuperConstructorFunctionDecl();
3368 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3380 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3383 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3384 Context->getPointerType(superType),
3385 CK_BitCast, SuperRep);
3389 new (Context)
InitListExpr(*Context, SourceLocation(), InitExprs,
3392 = Context->getTrivialTypeSourceInfo(superType);
3394 SourceLocation(), superTInfo, superType,
VK_PRValue, ILE,
false);
3396 MsgExprs.push_back(SuperRep);
3405 recExpr = CE->getSubExpr();
3408 ? CK_BlockPointerToObjCPointerCast
3409 : CK_CPointerToObjCPointerCast;
3411 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3413 MsgExprs.push_back(recExpr);
3421 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3422 SelExprs, StartLoc, EndLoc);
3423 MsgExprs.push_back(SelExp);
3426 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3432 if (needToScanForQualifiers(type))
3433 type = Context->getObjCIdType();
3435 (void)convertBlockPointerToFunctionPointer(type);
3439 type->isBooleanType()) {
3440 CK = CK_IntegralToBoolean;
3441 }
else if (type->isObjCObjectPointerType()) {
3443 CK = CK_BlockPointerToObjCPointerCast;
3445 CK = CK_CPointerToObjCPointerCast;
3453 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3456 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3457 if (CE->getType()->isObjCQualifiedIdType()) {
3458 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3459 userExpr = CE->getSubExpr();
3462 CK = CK_IntegralToPointer;
3464 CK = CK_BlockPointerToObjCPointerCast;
3466 CK = CK_CPointerToObjCPointerCast;
3470 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3474 MsgExprs.push_back(userExpr);
3486 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3487 ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
3489 ArgTypes.push_back(Context->getObjCIdType());
3490 ArgTypes.push_back(Context->getObjCSelType());
3495 ? Context->getObjCIdType()
3498 (void)convertBlockPointerToFunctionPointer(t);
3499 ArgTypes.push_back(t);
3502 convertToUnqualifiedObjCType(returnType);
3503 (void)convertBlockPointerToFunctionPointer(returnType);
3505 returnType = Context->getObjCIdType();
3512 *Context, MsgSendFlavor,
false, msgSendType,
VK_LValue, SourceLocation());
3518 cast = NoTypeInfoCStyleCastExpr(Context,
3519 Context->getPointerType(Context->VoidTy),
3526 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->
isVariadic() :
true);
3527 castType = Context->getPointerType(castType);
3528 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3537 Stmt *ReplacingStmt = CE;
3538 if (MsgSendStretFlavor) {
3544 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3548 ReplacingStmt = STCE;
3551 return ReplacingStmt;
3555 Stmt *ReplacingStmt =
3559 ReplaceStmt(Exp, ReplacingStmt);
3562 return ReplacingStmt;
3566QualType RewriteModernObjC::getProtocolType() {
3567 if (!ProtocolTypeDecl) {
3569 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3571 SourceLocation(), SourceLocation(),
3572 &Context->Idents.get(
"Protocol"),
3575 return Context->getTypeDeclType(ProtocolTypeDecl);
3583 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3587 SourceLocation(), ID, getProtocolType(),
3590 *Context, VD,
false, getProtocolType(),
VK_LValue, SourceLocation());
3592 Context, Context->getPointerType(DRE->
getType()), CK_BitCast, DRE);
3603 bool &IsNamedDefinition) {
3606 SourceLocation TagLocation;
3607 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3611 IsNamedDefinition =
true;
3613 return Context->getSourceManager().isBeforeInTranslationUnit(
3616 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3617 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3619 IsNamedDefinition =
true;
3620 TagLocation = ED->getLocation();
3621 return Context->getSourceManager().isBeforeInTranslationUnit(
3629bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3630 std::string &Result) {
3636 if (Type->isArrayType()) {
3637 QualType ElemTy = Context->getBaseElementType(Type);
3638 return RewriteObjCFieldDeclType(ElemTy, Result);
3640 else if (Type->isRecordType()) {
3641 auto *RD = Type->castAsRecordDecl();
3644 Result +=
"\n\tstruct ";
3646 Result +=
"\n\tunion ";
3648 assert(
false &&
"class not allowed as an ivar type");
3651 if (GlobalDefinedTags.count(RD)) {
3657 for (
auto *FD : RD->
fields())
3658 RewriteObjCFieldDecl(FD, Result);
3662 }
else if (
auto *ED = Type->getAsEnumDecl();
3663 ED && ED->isCompleteDefinition()) {
3664 Result +=
"\n\tenum ";
3665 Result += ED->getName();
3666 if (GlobalDefinedTags.count(ED)) {
3673 for (
const auto *EC : ED->enumerators()) {
3675 Result += EC->getName();
3677 Result +=
toString(EC->getInitVal(), 10);
3685 convertObjCTypeToCStyleType(Type);
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());
3703 Result += utostr(
fieldDecl->getBitWidthValue());
3705 else if (EleboratedType && Type->isArrayType()) {
3706 const ArrayType *AT = Context->getAsArrayType(Type);
3710 llvm::APInt Dim = CAT->getSize();
3711 Result += utostr(Dim.getZExtValue());
3724 std::string &Result) {
3728 if (Type->isArrayType())
3729 Type = Context->getBaseElementType(Type);
3731 auto *IDecl = dyn_cast<ObjCContainerDecl>(
fieldDecl->getDeclContext());
3733 if (
auto *TD = Type->getAsTagDecl()) {
3734 if (GlobalDefinedTags.count(TD))
3737 bool IsNamedDefinition =
false;
3738 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3739 RewriteObjCFieldDeclType(Type, Result);
3742 if (IsNamedDefinition)
3743 GlobalDefinedTags.insert(TD);
3747unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3749 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3750 return IvarGroupNumber[IV];
3752 unsigned GroupNo = 0;
3756 IVars.push_back(IVD);
3758 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3759 if (IVars[i]->isBitField()) {
3760 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3761 while (i < e && IVars[i]->isBitField())
3762 IvarGroupNumber[IVars[i++]] = GroupNo;
3767 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3768 return IvarGroupNumber[IV];
3771QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3774 std::string StructTagName;
3775 ObjCIvarBitfieldGroupType(IV, StructTagName);
3778 SourceLocation(), SourceLocation(), &Context->Idents.get(StructTagName));
3779 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3782 &Context->Idents.get(Ivar->
getName()),
3788 return Context->getCanonicalTagType(RD);
3793 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3794 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3795 if (
auto It = GroupRecordType.find(tuple); It != GroupRecordType.end())
3801 if (IVD->isBitField())
3804 if (!IVars.empty()) {
3805 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3807 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3808 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3813 if (!IVars.empty()) {
3815 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3816 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3817 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3819 QualType RetQT = GroupRecordType[tuple];
3820 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3827void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3828 std::string &Result) {
3831 Result +=
"__GRBF_";
3832 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3833 Result += utostr(GroupNo);
3839void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3840 std::string &Result) {
3844 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3845 Result += utostr(GroupNo);
3851void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3852 std::string &Result) {
3853 Result +=
"OBJC_IVAR_$_";
3854 ObjCIvarBitfieldGroupDecl(IV, Result);
3857#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3858 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3867 std::string &Result) {
3868 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3869 assert(CDecl->
getName() !=
"" &&
3870 "Name missing in SynthesizeObjCInternalStruct");
3875 IVars.push_back(IVD);
3880 const char *startBuf =
SM->getCharacterData(LocStart);
3881 const char *endBuf =
SM->getCharacterData(LocEnd);
3886 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3888 ReplaceText(LocStart, endBuf-startBuf, Result);
3895 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3896 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3900 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3901 if (IVars[i]->isBitField()) {
3903 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3904 RewriteObjCFieldDeclType(QT, Result);
3907 SKIP_BITFIELDS(i , e, IVars);
3910 Result +=
"\nstruct ";
3912 Result +=
"_IMPL {\n";
3914 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3917 Result +=
"_IVARS;\n";
3920 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3921 if (IVars[i]->isBitField()) {
3923 Result +=
"\tstruct ";
3924 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3925 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3927 SKIP_BITFIELDS(i , e, IVars);
3930 RewriteObjCFieldDecl(IVars[i], Result);
3935 ReplaceText(LocStart, endBuf-startBuf, Result);
3937 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3938 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3944 std::string &Result) {
3952 llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
3955 unsigned GroupNo = 0;
3957 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3958 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3962 if (LangOpts.MicrosoftExt)
3963 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3964 Result +=
"extern \"C\" ";
3965 if (LangOpts.MicrosoftExt &&
3968 Result +=
"__declspec(dllimport) ";
3970 Result +=
"unsigned long ";
3972 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3973 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3976 WriteInternalIvarName(CDecl, IvarDecl, Result);
3988void RewriteModernObjC::RewriteImplementations() {
3989 int ClsDefCount = ClassImplementation.size();
3990 int CatDefCount = CategoryImplementation.size();
3993 for (
int i = 0; i < ClsDefCount; i++) {
3998 "Legacy implicit interface rewriting not supported in moder abi");
3999 RewriteImplementationDecl(OIMP);
4002 for (
int i = 0; i < CatDefCount; i++) {
4007 "Legacy implicit interface rewriting not supported in moder abi");
4008 RewriteImplementationDecl(CIMP);
4012void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4013 const std::string &Name,
4015 assert(BlockByRefDeclNo.count(VD) &&
4016 "RewriteByRefString: ByRef decl missing");
4018 ResultStr +=
"struct ";
4019 ResultStr +=
"__Block_byref_" + Name +
4020 "_" + utostr(BlockByRefDeclNo[VD]) ;
4023static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4024 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4025 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4029std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4031 const std::string &Tag) {
4034 std::string StructRef =
"struct " + Tag;
4037 ConvertSourceLocationToLineDirective(BlockLoc, S);
4039 S +=
"static " + RT.
getAsString(Context->getPrintingPolicy()) +
" __" +
4040 funcName.str() +
"_block_func_" + utostr(i);
4047 S +=
"(" + StructRef +
" *__cself)";
4049 S +=
"(" + StructRef +
" *__cself)";
4052 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4055 S += StructRef +
" *__cself, ";
4056 std::string ParamStr;
4060 ParamStr = (*AI)->getNameAsString();
4062 (void)convertBlockPointerToFunctionPointer(QT);
4079 std::string TypeString;
4080 RewriteByRefString(TypeString, Name, VD);
4082 Name = TypeString + Name;
4083 S += Name +
" = __cself->" + VD->
getNameAsString() +
"; // bound by ref\n";
4086 for (
ValueDecl *VD : BlockByCopyDecls) {
4098 if (isTopLevelBlockPointerType(VD->
getType())) {
4099 RewriteBlockPointerTypeVariable(S, VD);
4101 RewriteBlockPointerType(S, VD->
getType());
4107 if (HasLocalVariableExternalStorage(VD))
4108 QT = Context->getPointerType(QT);
4111 "; // bound by copy\n";
4114 std::string RewrittenStr = RewrittenBlockExprs[CE];
4115 const char *cstr = RewrittenStr.c_str();
4116 while (*cstr++ !=
'{') ;
4122std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
4123 BlockExpr *CE,
int i, StringRef funcName,
const std::string &Tag) {
4124 std::string StructRef =
"struct " + Tag;
4125 std::string S =
"static void __";
4128 S +=
"_block_copy_" + utostr(i);
4129 S +=
"(" + StructRef;
4130 S +=
"*dst, " + StructRef;
4132 for (
ValueDecl *VD : ImportedBlockDecls) {
4133 S +=
"_Block_object_assign((void*)&dst->";
4135 S +=
", (void*)src->";
4137 if (BlockByRefDecls.count(VD))
4138 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4140 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4142 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4146 S +=
"\nstatic void __";
4148 S +=
"_block_dispose_" + utostr(i);
4149 S +=
"(" + StructRef;
4151 for (
ValueDecl *VD : ImportedBlockDecls) {
4152 S +=
"_Block_object_dispose((void*)src->";
4154 if (BlockByRefDecls.count(VD))
4155 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4157 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4159 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4165std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE,
4166 const std::string &Tag,
4167 const std::string &Desc) {
4168 std::string S =
"\nstruct " + Tag;
4171 S +=
" {\n struct __block_impl impl;\n";
4172 S +=
" struct " + Desc;
4179 if (BlockDeclRefs.size()) {
4181 for (
ValueDecl *VD : BlockByCopyDecls) {
4184 std::string ArgName =
"_" + FieldName;
4195 if (isTopLevelBlockPointerType(VD->
getType())) {
4196 S +=
"struct __block_impl *";
4200 if (HasLocalVariableExternalStorage(VD))
4201 QT = Context->getPointerType(QT);
4206 S += FieldName +
";\n";
4212 std::string ArgName =
"_" + FieldName;
4214 std::string TypeString;
4215 RewriteByRefString(TypeString, FieldName, VD);
4217 FieldName = TypeString + FieldName;
4218 ArgName = TypeString + ArgName;
4221 S += FieldName +
"; // by ref\n";
4226 bool firsTime =
true;
4227 for (
const ValueDecl *VD : BlockByCopyDecls) {
4234 if (isTopLevelBlockPointerType(VD->
getType()))
4235 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4240 for (
const ValueDecl *VD : BlockByRefDecls) {
4248 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4253 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4255 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4256 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4263 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4265 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4266 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4276std::string RewriteModernObjC::SynthesizeBlockDescriptor(
4277 const std::string &DescTag,
const std::string &ImplTag,
int i,
4278 StringRef FunName,
unsigned hasCopy) {
4279 std::string S =
"\nstatic struct " + DescTag;
4281 S +=
" {\n size_t reserved;\n";
4282 S +=
" size_t Block_size;\n";
4284 S +=
" void (*copy)(struct ";
4285 S += ImplTag; S +=
"*, struct ";
4286 S += ImplTag; S +=
"*);\n";
4288 S +=
" void (*dispose)(struct ";
4289 S += ImplTag; S +=
"*);\n";
4293 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4296 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4297 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4303void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
4304 StringRef FunName) {
4305 bool RewriteSC = (GlobalVarDecl &&
4310 std::string SC(
" void __");
4313 InsertText(FunLocStart, SC);
4317 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4318 CollectBlockDeclRefInfo(Blocks[i]);
4321 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4324 BlockDeclRefs.push_back(Exp);
4325 if (!VD->
hasAttr<BlocksAttr>()) {
4326 BlockByCopyDecls.insert(VD);
4330 BlockByRefDecls.insert(VD);
4336 ImportedBlockDecls.insert(VD);
4339 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4340 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4342 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4344 InsertText(FunLocStart, CI);
4346 std::string
CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4348 InsertText(FunLocStart, CF);
4350 if (ImportedBlockDecls.size()) {
4351 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4352 InsertText(FunLocStart, HF);
4354 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4355 ImportedBlockDecls.size() > 0);
4356 InsertText(FunLocStart, BD);
4358 BlockDeclRefs.clear();
4359 BlockByRefDecls.clear();
4360 BlockByCopyDecls.clear();
4361 ImportedBlockDecls.clear();
4375 InsertText(FunLocStart, SC);
4377 if (GlobalConstructionExp) {
4381 std::string Tag =
"__";
4383 Tag +=
"_block_impl_";
4384 Tag += utostr(Blocks.size()-1);
4385 std::string globalBuf =
"static ";
4386 globalBuf += Tag; globalBuf +=
" ";
4389 llvm::raw_string_ostream constructorExprBuf(SStr);
4390 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4394 InsertText(FunLocStart, globalBuf);
4395 GlobalConstructionExp =
nullptr;
4399 InnerDeclRefsCount.clear();
4400 InnerDeclRefs.clear();
4401 RewrittenBlockExprs.clear();
4404void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4405 SourceLocation FunLocStart =
4406 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4407 : FD->getTypeSpecStartLoc();
4408 StringRef FuncName = FD->
getName();
4410 SynthesizeBlockLiterals(FunLocStart, FuncName);
4413static void BuildUniqueMethodName(std::string &Name,
4416 Name = std::string(IFace->
getName());
4419 std::string::size_type loc = 0;
4420 while ((loc = Name.find(
':', loc)) != std::string::npos)
4421 Name.replace(loc, 1,
"_");
4424void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4428 std::string FuncName;
4429 BuildUniqueMethodName(FuncName, MD);
4430 SynthesizeBlockLiterals(FunLocStart, FuncName);
4433void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4436 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4437 GetBlockDeclRefExprs(CBE->getBody());
4439 GetBlockDeclRefExprs(SubStmt);
4444 HasLocalVariableExternalStorage(DRE->
getDecl()))
4446 BlockDeclRefs.push_back(DRE);
4449void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4451 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4454 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4456 GetInnerBlockDeclRefExprs(CBE->getBody(),
4461 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4464 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4466 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4468 InnerBlockDeclRefs.push_back(DRE);
4470 if (Var->isFunctionOrMethodVarDecl())
4471 ImportedLocalExternalDecls.insert(Var);
4479bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4481 convertBlockPointerToFunctionPointer(T);
4482 if (T->isFunctionPointerType()) {
4484 if (
const PointerType* PT = T->getAs<PointerType>()) {
4485 PointeeTy = PT->getPointeeType();
4487 T = convertFunctionTypeOfBlocks(FT);
4488 T = Context->getPointerType(T);
4493 convertToUnqualifiedObjCType(T);
4507 bool modified = convertObjCTypeToCStyleType(Res);
4513 if (convertObjCTypeToCStyleType(t))
4515 ArgTypes.push_back(t);
4520 FuncType = getSimpleFunctionType(Res, ArgTypes);
4525Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4529 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4531 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4534 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4535 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4537 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4540 dyn_cast<ConditionalOperator>(BlockExp)) {
4541 Expr *LHSExp = CEXPR->getLHS();
4542 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4543 Expr *RHSExp = CEXPR->getRHS();
4544 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4545 Expr *CONDExp = CEXPR->getCond();
4547 CONDExp, SourceLocation(),
cast<Expr>(LHSStmt), SourceLocation(),
4550 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4553 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4556 assert(
false &&
"RewriteBlockClass: Bad type");
4558 assert(CPT &&
"RewriteBlockClass: Bad type");
4560 assert(FT &&
"RewriteBlockClass: Bad type");
4565 SourceLocation(), SourceLocation(),
4566 &Context->Idents.get(
"__block_impl"));
4567 QualType PtrBlock = Context->getPointerType(Context->getCanonicalTagType(RD));
4573 ArgTypes.push_back(PtrBlock);
4578 if (!convertBlockPointerToFunctionPointer(t))
4579 convertToUnqualifiedObjCType(t);
4580 ArgTypes.push_back(t);
4584 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4586 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4588 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4590 const_cast<Expr*
>(BlockExp));
4598 &Context->Idents.get(
"FuncPtr"),
4599 Context->VoidPtrTy,
nullptr,
4605 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4607 PE =
new (Context)
ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
4611 BlkExprs.push_back(BlkCast);
4614 E = Exp->
arg_end(); I != E; ++I) {
4615 BlkExprs.push_back(*I);
4636Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4641 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4645 &Context->Idents.get(
"__forwarding"),
4646 Context->VoidPtrTy,
nullptr,
4652 StringRef Name = VD->
getName();
4654 &Context->Idents.get(Name),
4655 Context->VoidPtrTy,
nullptr,
4665 ReplaceStmt(DeclRefExp, PE);
4672Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4674 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4675 if (!ImportedLocalExternalDecls.count(Var))
4683 ReplaceStmt(DRE, PE);
4692 if (LocStart.isInvalid())
4698 const char *startBuf =
SM->getCharacterData(LocStart);
4699 const char *endBuf =
SM->getCharacterData(LocEnd);
4701 const Type* TypePtr = QT->
getAs<Type>();
4705 std::string TypeAsString =
"(";
4706 RewriteBlockPointerType(TypeAsString, QT);
4707 TypeAsString +=
")";
4708 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4712 const char *argPtr = startBuf;
4714 while (*argPtr++ && (argPtr < endBuf)) {
4718 LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
4719 ReplaceText(LocStart, 1,
"*");
4725void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4727 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4728 CastKind != CK_AnyPointerToBlockPointerCast)
4732 (void)convertBlockPointerToFunctionPointer(QT);
4733 std::string TypeString(QT.
getAsString(Context->getPrintingPolicy()));
4734 std::string Str =
"(";
4740void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4742 unsigned parenCount = 0;
4745 const char *startBuf =
SM->getCharacterData(DeclLoc);
4746 const char *startArgList = strchr(startBuf,
'(');
4748 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4752 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
4753 assert((DeclLoc.isValid()) &&
"Invalid DeclLoc");
4755 const char *argPtr = startArgList;
4757 while (*argPtr++ && parenCount) {
4761 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
4762 ReplaceText(DeclLoc, 1,
"*");
4774bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4776 const PointerType *PT = QT->
getAs<PointerType>();
4781 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4786 if (isTopLevelBlockPointerType(I))
4792bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4794 const PointerType *PT = QT->
getAs<PointerType>();
4799 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4804 if (I->isObjCQualifiedIdType())
4806 if (I->isObjCObjectPointerType() &&
4807 I->getPointeeType()->isObjCQualifiedInterfaceType())
4815void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4816 const char *&RParen) {
4817 const char *argPtr = strchr(Name,
'(');
4818 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4822 unsigned parenCount = 1;
4824 while (*argPtr && parenCount) {
4826 case '(': parenCount++;
break;
4827 case ')': parenCount--;
break;
4830 if (parenCount) argPtr++;
4832 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4836void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4838 RewriteBlockPointerFunctionArgs(FD);
4844 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4847 DeclT = TDD->getUnderlyingType();
4848 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4851 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4853 const char *startBuf =
SM->getCharacterData(DeclLoc);
4854 const char *endBuf = startBuf;
4856 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4858 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
4860 unsigned OrigLength=0;
4863 if (*startBuf ==
'^') {
4869 while (*startBuf !=
')') {
4877 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4878 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4882 startBuf =
SM->getCharacterData(DeclLoc);
4883 const char *argListBegin, *argListEnd;
4884 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4885 while (argListBegin < argListEnd) {
4886 if (*argListBegin ==
'^')
4888 else if (*argListBegin ==
'<') {
4890 buf += *argListBegin++;
4892 while (*argListBegin !=
'>') {
4893 buf += *argListBegin++;
4896 buf += *argListBegin;
4900 buf += *argListBegin;
4907 ReplaceText(Start, OrigLength, buf);
4930std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4933 if (CopyDestroyCache.count(flag))
4935 CopyDestroyCache.insert(flag);
4936 S =
"static void __Block_byref_id_object_copy_";
4938 S +=
"(void *dst, void *src) {\n";
4943 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4944 unsigned VoidPtrSize =
4945 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4947 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4948 S +=
" _Block_object_assign((char*)dst + ";
4949 S += utostr(offset);
4950 S +=
", *(void * *) ((char*)src + ";
4951 S += utostr(offset);
4956 S +=
"static void __Block_byref_id_object_dispose_";
4958 S +=
"(void *src) {\n";
4959 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4960 S += utostr(offset);
4985void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
4990 if (DeclLoc.isInvalid())
4994 const char *startBuf =
SM->getCharacterData(DeclLoc);
4996 X =
SM->getExpansionLoc(
X);
4997 const char *endBuf =
SM->getCharacterData(
X);
4999 std::string ByrefType;
5000 RewriteByRefString(ByrefType, Name, ND,
true);
5001 ByrefType +=
" {\n";
5002 ByrefType +=
" void *__isa;\n";
5003 RewriteByRefString(ByrefType, Name, ND);
5004 ByrefType +=
" *__forwarding;\n";
5005 ByrefType +=
" int __flags;\n";
5006 ByrefType +=
" int __size;\n";
5010 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
5011 if (HasCopyAndDispose) {
5012 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5013 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5017 (void)convertBlockPointerToFunctionPointer(T);
5020 ByrefType +=
" " + Name +
";\n";
5021 ByrefType +=
"};\n";
5023 SourceLocation FunLocStart;
5025 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5027 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5030 InsertText(FunLocStart, ByrefType);
5036 if (HasCopyAndDispose) {
5044 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5052 bool hasInit = (ND->
getInit() !=
nullptr);
5063 if (HasCopyAndDispose)
5067 RewriteByRefString(ByrefType, Name, ND);
5068 std::string ForwardingCastType(
"(");
5069 ForwardingCastType += ByrefType +
" *)";
5070 ByrefType +=
" " + Name +
" = {(void*)";
5071 ByrefType += utostr(
isa);
5072 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5073 ByrefType += utostr(flags);
5075 ByrefType +=
"sizeof(";
5076 RewriteByRefString(ByrefType, Name, ND);
5078 if (HasCopyAndDispose) {
5079 ByrefType +=
", __Block_byref_id_object_copy_";
5080 ByrefType += utostr(flag);
5081 ByrefType +=
", __Block_byref_id_object_dispose_";
5082 ByrefType += utostr(flag);
5090 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5091 const char *commaBuf = startDeclBuf;
5092 while (*commaBuf !=
',')
5094 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5095 DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
5096 startBuf = commaBuf;
5100 ByrefType +=
"};\n";
5101 unsigned nameSize = Name.size();
5106 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5110 SourceLocation startLoc;
5113 startLoc = ECE->getLParenLoc();
5116 startLoc =
SM->getExpansionLoc(startLoc);
5117 endBuf =
SM->getCharacterData(startLoc);
5118 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5120 const char separator = lastDecl ?
';' :
',';
5121 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5122 const char *separatorBuf = strchr(startInitializerBuf, separator);
5123 assert((*separatorBuf == separator) &&
5124 "RewriteByRefVar: can't find ';' or ','");
5125 SourceLocation separatorLoc =
5126 startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
5128 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5132void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5134 GetBlockDeclRefExprs(Exp->
getBody());
5135 if (BlockDeclRefs.size()) {
5137 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5139 BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
5141 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5143 BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
5145 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5147 BlockDeclRefs[i]->
getType()->isObjCObjectPointerType() ||
5148 BlockDeclRefs[i]->
getType()->isBlockPointerType())
5149 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5153FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5155 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5157 SourceLocation(), ID, FType,
nullptr,
SC_Extern,
5165 Blocks.push_back(Exp);
5167 CollectBlockDeclRefInfo(Exp);
5170 int countOfInnerDecls = 0;
5171 if (!InnerBlockDeclRefs.empty()) {
5172 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5175 if (!VD->
hasAttr<BlocksAttr>() && BlockByCopyDecls.insert(VD)) {
5179 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5180 BlockDeclRefs.push_back(Exp);
5182 if (VD->
hasAttr<BlocksAttr>() && BlockByRefDecls.insert(VD)) {
5183 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5184 BlockDeclRefs.push_back(Exp);
5188 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5190 InnerBlockDeclRefs[i]->
getType()->isObjCObjectPointerType() ||
5191 InnerBlockDeclRefs[i]->
getType()->isBlockPointerType())
5192 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5194 InnerDeclRefsCount.push_back(countOfInnerDecls);
5196 std::string FuncName;
5200 else if (CurMethodDef)
5201 BuildUniqueMethodName(FuncName, CurMethodDef);
5202 else if (GlobalVarDecl)
5205 bool GlobalBlockExpr =
5208 if (GlobalBlockExpr && !GlobalVarDecl) {
5210 GlobalBlockExpr =
false;
5213 std::string BlockNumber = utostr(Blocks.size()-1);
5215 std::string
Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5218 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5219 QualType FType = Context->getPointerType(BFT);
5227 if (GlobalBlockExpr)
5231 Tag += FuncName +
"_block_impl_" + BlockNumber;
5233 FD = SynthBlockInitFunctionDecl(Tag);
5240 FD = SynthBlockInitFunctionDecl(
Func);
5248 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5251 *Context, TUDecl, SourceLocation(), SourceLocation(),
5252 &Context->Idents.get(DescData), Context->VoidPtrTy,
nullptr,
SC_Static);
5255 new (Context)
DeclRefExpr(*Context, NewVD,
false, Context->VoidPtrTy,
5257 UO_AddrOf, Context->getPointerType(Context->VoidPtrTy),
VK_PRValue,
5259 InitExprs.push_back(DescRefExpr);
5262 if (BlockDeclRefs.size()) {
5265 for (
ValueDecl *VD : BlockByCopyDecls) {
5266 if (isObjCType(VD->
getType())) {
5268 FD = SynthBlockInitFunctionDecl(VD->
getName());
5271 if (HasLocalVariableExternalStorage(VD)) {
5273 QT = Context->getPointerType(QT);
5276 SourceLocation(),
false,
5279 }
else if (isTopLevelBlockPointerType(VD->
getType())) {
5280 FD = SynthBlockInitFunctionDecl(VD->
getName());
5283 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5286 FD = SynthBlockInitFunctionDecl(VD->
getName());
5289 if (HasLocalVariableExternalStorage(VD)) {
5291 QT = Context->getPointerType(QT);
5294 SourceLocation(),
false,
5298 InitExprs.push_back(Exp);
5303 std::string RecName;
5304 RewriteByRefString(RecName, Name, ND,
true);
5306 +
sizeof(
"struct"));
5309 SourceLocation(), SourceLocation(), II);
5310 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5312 Context->getPointerType(Context->getCanonicalTagType(RD));
5314 FD = SynthBlockInitFunctionDecl(ND->
getName());
5317 bool isNestedCapturedVar =
false;
5318 for (
const auto &CI : block->
captures()) {
5319 const VarDecl *variable = CI.getVariable();
5320 if (variable == ND && CI.isNested()) {
5321 assert(CI.isByRef() &&
5322 "SynthBlockInitExpr - captured block variable is not byref");
5323 isNestedCapturedVar =
true;
5329 if (!isNestedCapturedVar)
5331 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5334 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5335 InitExprs.push_back(Exp);
5338 if (ImportedBlockDecls.size()) {
5342 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5344 Context->IntTy, SourceLocation());
5345 InitExprs.push_back(FlagExp);
5350 if (GlobalBlockExpr) {
5351 assert (!GlobalConstructionExp &&
5352 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5353 GlobalConstructionExp = NewRep;
5358 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5361 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5364 NewRep =
new (Context)
ParenExpr(SourceLocation(), SourceLocation(),
5367 BlockDeclRefs.clear();
5368 BlockByRefDecls.clear();
5369 BlockByCopyDecls.clear();
5370 ImportedBlockDecls.clear();
5374bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5376 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5377 return CS->getElement() == DS;
5385Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5391 ObjCBcLabelNo.push_back(++BcLabelCount);
5398 return RewritePropertyOrImplicitSetter(PseudoOp);
5400 return RewritePropertyOrImplicitGetter(PseudoOp);
5402 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5403 return RewriteObjCIvarRefExpr(IvarRefExpr);
5413 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5415 childStmt = newStmt;
5419 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5422 InnerContexts.insert(BE->getBlockDecl());
5423 ImportedLocalExternalDecls.clear();
5424 GetInnerBlockDeclRefExprs(BE->getBody(),
5425 InnerBlockDeclRefs, InnerContexts);
5427 Stmt *SaveCurrentBody = CurrentBody;
5428 CurrentBody = BE->getBody();
5429 PropParentMap =
nullptr;
5435 bool saveDisableReplaceStmt = DisableReplaceStmt;
5436 DisableReplaceStmt =
false;
5437 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5438 DisableReplaceStmt = saveDisableReplaceStmt;
5439 CurrentBody = SaveCurrentBody;
5440 PropParentMap =
nullptr;
5441 ImportedLocalExternalDecls.clear();
5443 std::string Str =
Rewrite.getRewrittenText(BE->getSourceRange());
5444 RewrittenBlockExprs[BE] = Str;
5446 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5449 ReplaceStmt(S, blockTranscribed);
5450 return blockTranscribed;
5454 return RewriteAtEncode(AtEncode);
5457 return RewriteAtSelector(AtSelector);
5460 return RewriteObjCStringLiteral(AtString);
5463 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5466 return RewriteObjCBoxedExpr(BoxedExpr);
5469 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5472 dyn_cast<ObjCDictionaryLiteral>(S))
5473 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5478 SourceLocation startLoc = MessExpr->getBeginLoc();
5479 SourceLocation endLoc = MessExpr->getEndLoc();
5481 const char *startBuf =
SM->getCharacterData(startLoc);
5482 const char *endBuf =
SM->getCharacterData(endLoc);
5484 std::string messString;
5485 messString +=
"// ";
5486 messString.append(startBuf, endBuf-startBuf+1);
5495 return RewriteMessageExpr(MessExpr);
5499 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5500 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5504 return RewriteObjCTryStmt(StmtTry);
5507 return RewriteObjCSynchronizedStmt(StmtTry);
5510 return RewriteObjCThrowStmt(StmtThrow);
5513 return RewriteObjCProtocolExpr(ProtocolExp);
5516 dyn_cast<ObjCForCollectionStmt>(S))
5517 return RewriteObjCForCollectionStmt(StmtForCollection,
5518 OrigStmtRange.getEnd());
5520 dyn_cast<BreakStmt>(S))
5521 return RewriteBreakStmt(StmtBreakStmt);
5523 dyn_cast<ContinueStmt>(S))
5524 return RewriteContinueStmt(StmtContinueStmt);
5528 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5538 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5539 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5545 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5546 if (isTopLevelBlockPointerType(ND->
getType()))
5547 RewriteBlockPointerDecl(ND);
5549 CheckFunctionPointerDecl(ND->
getType(), ND);
5550 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5551 if (VD->
hasAttr<BlocksAttr>()) {
5552 static unsigned uniqueByrefDeclCount = 0;
5553 assert(!BlockByRefDeclNo.count(ND) &&
5554 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5555 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5556 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5559 RewriteTypeOfDecl(VD);
5563 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5564 RewriteBlockPointerDecl(TD);
5565 else if (TD->getUnderlyingType()->isFunctionPointerType())
5566 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5572 RewriteObjCQualifiedInterfaceTypes(CE);
5576 assert(!Stmts.empty() &&
"Statement stack is empty");
5579 &&
"Statement stack mismatch");
5583 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5585 if (VD->
hasAttr<BlocksAttr>())
5586 return RewriteBlockDeclRefExpr(DRE);
5587 if (HasLocalVariableExternalStorage(VD))
5588 return RewriteLocalVariableExternalStorage(DRE);
5591 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5593 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5594 ReplaceStmt(S, BlockCall);
5599 RewriteCastExpr(CE);
5602 RewriteImplicitCastObjCExpr(ICE);
5612 llvm::raw_string_ostream Buf(SStr);
5613 Replacement->printPretty(Buf);
5614 const std::string &Str = Buf.str();
5616 printf(
"CAST = %s\n", &Str[0]);
5626void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5627 for (
auto *FD : RD->
fields()) {
5628 if (isTopLevelBlockPointerType(FD->
getType()))
5629 RewriteBlockPointerDecl(FD);
5632 RewriteObjCQualifiedInterfaceTypes(FD);
5638void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5640 case Decl::Function: {
5648 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5655 CurFunctionDef = FD;
5658 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5660 CurrentBody =
nullptr;
5661 if (PropParentMap) {
5662 delete PropParentMap;
5663 PropParentMap =
nullptr;
5667 InsertBlockLiteralsWithinFunction(FD);
5668 RewriteLineDirective(D);
5669 CurFunctionDef =
nullptr;
5673 case Decl::ObjCMethod: {
5679 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5681 CurrentBody =
nullptr;
5682 if (PropParentMap) {
5683 delete PropParentMap;
5684 PropParentMap =
nullptr;
5686 InsertBlockLiteralsWithinMethod(MD);
5687 RewriteLineDirective(D);
5688 CurMethodDef =
nullptr;
5692 case Decl::ObjCImplementation: {
5694 ClassImplementation.push_back(CI);
5697 case Decl::ObjCCategoryImpl: {
5699 CategoryImplementation.push_back(CI);
5704 RewriteObjCQualifiedInterfaceTypes(VD);
5705 if (isTopLevelBlockPointerType(VD->
getType()))
5706 RewriteBlockPointerDecl(VD);
5708 CheckFunctionPointerDecl(VD->
getType(), VD);
5711 RewriteCastExpr(CE);
5717 RewriteRecordBody(RD);
5722 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5723 CurrentBody =
nullptr;
5724 if (PropParentMap) {
5725 delete PropParentMap;
5726 PropParentMap =
nullptr;
5729 GlobalVarDecl =
nullptr;
5733 RewriteCastExpr(CE);
5738 case Decl::TypeAlias:
5739 case Decl::Typedef: {
5741 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5742 RewriteBlockPointerDecl(TD);
5743 else if (TD->getUnderlyingType()->isFunctionPointerType())
5744 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5746 RewriteObjCQualifiedInterfaceTypes(TD);
5750 case Decl::CXXRecord:
5751 case Decl::Record: {
5754 RewriteRecordBody(RD);
5766static void Write_ProtocolExprReferencedMetadata(
ASTContext *Context,
5768 std::string &Result) {
5770 if (Context->getLangOpts().MicrosoftExt)
5771 Result +=
"static ";
5772 Result +=
"struct _protocol_t *";
5773 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5780void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5786 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5791 HandleTopLevelSingleDecl(FDecl);
5797 RewriteObjCProtocolMetaData(ProtDecl,
Preamble);
5798 Write_ProtocolExprReferencedMetadata(Context, ProtDecl,
Preamble);
5801 InsertText(
SM->getLocForStartOfFile(MainFileID),
Preamble,
false);
5803 if (ClassImplementation.size() || CategoryImplementation.size())
5804 RewriteImplementations();
5806 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5812 RewriteInterfaceDecl(CDecl);
5817 if (
const RewriteBuffer *RewriteBuf =
5818 Rewrite.getRewriteBufferFor(MainFileID)) {
5820 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5822 llvm::errs() <<
"No changes\n";
5825 if (ClassImplementation.size() || CategoryImplementation.size() ||
5826 ProtocolExprDecls.size()) {
5828 std::string ResultStr;
5829 RewriteMetaDataIntoBuffer(ResultStr);
5831 *OutFile << ResultStr;
5835 std::string ResultStr;
5836 WriteImageInfo(ResultStr);
5837 *OutFile << ResultStr;
5842void RewriteModernObjC::Initialize(
ASTContext &context) {
5843 InitializeCommon(context);
5853 Preamble +=
"struct objc_selector; struct objc_class;\n";
5854 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5855 Preamble +=
"\n\tstruct objc_object *superClass; ";
5857 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5858 Preamble +=
": object(o), superClass(s) {} ";
5861 if (LangOpts.MicrosoftExt) {
5864 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5865 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5866 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5867 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5868 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5870 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5871 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5872 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5873 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5877 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5878 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5879 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5882 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5883 Preamble +=
"typedef struct objc_object Protocol;\n";
5884 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5886 if (LangOpts.MicrosoftExt) {
5887 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5888 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5891 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5893 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5894 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5895 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5896 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5897 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5899 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5901 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5902 Preamble +=
"(struct objc_class *);\n";
5903 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5905 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5907 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5908 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5909 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5911 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5913 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5915 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5916 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5917 Preamble +=
"unsigned long state;\n\t";
5918 Preamble +=
"void **itemsPtr;\n\t";
5919 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5920 Preamble +=
"unsigned long extra[5];\n};\n";
5921 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5922 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5924 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5925 Preamble +=
"struct __NSConstantStringImpl {\n";
5930 Preamble +=
" long long length;\n";
5935 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5936 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5938 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5940 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5943 Preamble +=
"#ifndef BLOCK_IMPL\n";
5944 Preamble +=
"#define BLOCK_IMPL\n";
5945 Preamble +=
"struct __block_impl {\n";
5951 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5952 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5953 Preamble +=
"extern \"C\" __declspec(dllexport) "
5954 "void _Block_object_assign(void *, const void *, const int);\n";
5955 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5956 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5957 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
5959 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
5960 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
5961 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
5962 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
5965 if (LangOpts.MicrosoftExt) {
5966 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
5967 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
5968 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
5969 Preamble +=
"#define __attribute__(X)\n";
5984 Preamble +=
"\n#include <stdarg.h>\n";
5985 Preamble +=
"struct __NSContainer_literal {\n";
5987 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
5989 Preamble +=
"\tva_start(marker, count);\n";
5990 Preamble +=
"\tarr = new void *[count];\n";
5991 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
5992 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
5993 Preamble +=
"\tva_end( marker );\n";
5995 Preamble +=
" ~__NSContainer_literal() {\n";
6001 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6002 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6003 Preamble +=
"struct __AtAutoreleasePool {\n";
6004 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6005 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6006 Preamble +=
" void * atautoreleasepoolobj;\n";
6011 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6016void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6017 std::string &Result) {
6018 Result +=
"__OFFSETOFIVAR__(struct ";
6020 if (LangOpts.MicrosoftExt)
6024 ObjCIvarBitfieldGroupDecl(ivar, Result);
6132static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6133 static bool meta_data_declared =
false;
6134 if (meta_data_declared)
6137 Result +=
"\nstruct _prop_t {\n";
6138 Result +=
"\tconst char *name;\n";
6139 Result +=
"\tconst char *attributes;\n";
6142 Result +=
"\nstruct _protocol_t;\n";
6144 Result +=
"\nstruct _objc_method {\n";
6145 Result +=
"\tstruct objc_selector * _cmd;\n";
6146 Result +=
"\tconst char *method_type;\n";
6147 Result +=
"\tvoid *_imp;\n";
6150 Result +=
"\nstruct _protocol_t {\n";
6151 Result +=
"\tvoid * isa; // NULL\n";
6152 Result +=
"\tconst char *protocol_name;\n";
6153 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6154 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6155 Result +=
"\tconst struct method_list_t *class_methods;\n";
6156 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6157 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6158 Result +=
"\tconst struct _prop_list_t * properties;\n";
6159 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6160 Result +=
"\tconst unsigned int flags; // = 0\n";
6161 Result +=
"\tconst char ** extendedMethodTypes;\n";
6164 Result +=
"\nstruct _ivar_t {\n";
6165 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6166 Result +=
"\tconst char *name;\n";
6167 Result +=
"\tconst char *type;\n";
6168 Result +=
"\tunsigned int alignment;\n";
6169 Result +=
"\tunsigned int size;\n";
6172 Result +=
"\nstruct _class_ro_t {\n";
6173 Result +=
"\tunsigned int flags;\n";
6174 Result +=
"\tunsigned int instanceStart;\n";
6175 Result +=
"\tunsigned int instanceSize;\n";
6176 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6177 if (Triple.getArch() == llvm::Triple::x86_64)
6178 Result +=
"\tunsigned int reserved;\n";
6179 Result +=
"\tconst unsigned char *ivarLayout;\n";
6180 Result +=
"\tconst char *name;\n";
6181 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6182 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6183 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6184 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6185 Result +=
"\tconst struct _prop_list_t *properties;\n";
6188 Result +=
"\nstruct _class_t {\n";
6189 Result +=
"\tstruct _class_t *isa;\n";
6190 Result +=
"\tstruct _class_t *superclass;\n";
6191 Result +=
"\tvoid *cache;\n";
6192 Result +=
"\tvoid *vtable;\n";
6193 Result +=
"\tstruct _class_ro_t *ro;\n";
6196 Result +=
"\nstruct _category_t {\n";
6197 Result +=
"\tconst char *name;\n";
6198 Result +=
"\tstruct _class_t *cls;\n";
6199 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6200 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6201 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6202 Result +=
"\tconst struct _prop_list_t *properties;\n";
6205 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6206 Result +=
"#pragma warning(disable:4273)\n";
6207 meta_data_declared =
true;
6210static void Write_protocol_list_t_TypeDecl(std::string &Result,
6211 long super_protocol_count) {
6212 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6213 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6214 Result +=
"\tstruct _protocol_t *super_protocols[";
6215 Result += utostr(super_protocol_count); Result +=
"];\n";
6219static void Write_method_list_t_TypeDecl(std::string &Result,
6220 unsigned int method_count) {
6221 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6222 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6223 Result +=
"\tunsigned int method_count;\n";
6224 Result +=
"\tstruct _objc_method method_list[";
6225 Result += utostr(method_count); Result +=
"];\n";
6229static void Write__prop_list_t_TypeDecl(std::string &Result,
6230 unsigned int property_count) {
6231 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6232 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6233 Result +=
"\tunsigned int count_of_properties;\n";
6234 Result +=
"\tstruct _prop_t prop_list[";
6235 Result += utostr(property_count); Result +=
"];\n";
6239static void Write__ivar_list_t_TypeDecl(std::string &Result,
6240 unsigned int ivar_count) {
6241 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6242 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6243 Result +=
"\tunsigned int count;\n";
6244 Result +=
"\tstruct _ivar_t ivar_list[";
6245 Result += utostr(ivar_count); Result +=
"];\n";
6249static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6252 StringRef ProtocolName) {
6253 if (SuperProtocols.size() > 0) {
6254 Result +=
"\nstatic ";
6255 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6256 Result +=
" "; Result += VarName;
6257 Result += ProtocolName;
6258 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6259 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6260 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6262 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6272static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6276 StringRef TopLevelDeclName,
6278 if (Methods.size() > 0) {
6279 Result +=
"\nstatic ";
6280 Write_method_list_t_TypeDecl(Result, Methods.size());
6281 Result +=
" "; Result += VarName;
6282 Result += TopLevelDeclName;
6283 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6284 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6285 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6286 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6289 Result +=
"\t{{(struct objc_selector *)\"";
6291 Result +=
"\t{(struct objc_selector *)\"";
6292 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6294 std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(MD);
6295 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6300 Result +=
"(void *)";
6301 Result += RewriteObj.MethodInternalNames[MD];
6312static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6315 const Decl *Container,
6317 StringRef ProtocolName) {
6318 if (Properties.size() > 0) {
6319 Result +=
"\nstatic ";
6320 Write__prop_list_t_TypeDecl(Result, Properties.size());
6321 Result +=
" "; Result += VarName;
6322 Result += ProtocolName;
6323 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6324 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6325 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6326 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6332 Result += PropDecl->
getName(); Result +=
"\",";
6333 std::string PropertyTypeString =
6334 Context->getObjCEncodingForPropertyDecl(PropDecl, Container);
6335 std::string QuotePropertyTypeString;
6336 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6337 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6352 OBJC2_CLS_HIDDEN = 0x10,
6353 CLS_EXCEPTION = 0x20,
6356 CLS_HAS_IVAR_RELEASER = 0x40,
6358 CLS_COMPILED_BY_ARC = 0x80
6361static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6363 const std::string &InstanceStart,
6364 const std::string &InstanceSize,
6370 StringRef ClassName) {
6371 Result +=
"\nstatic struct _class_ro_t ";
6372 Result += VarName; Result += ClassName;
6373 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6375 Result += llvm::utostr(flags); Result +=
", ";
6376 Result += InstanceStart; Result +=
", ";
6377 Result += InstanceSize; Result +=
", \n";
6379 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6380 if (Triple.getArch() == llvm::Triple::x86_64)
6382 Result +=
"(unsigned int)0, \n\t";
6384 Result +=
"0, \n\t";
6385 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6386 bool metaclass = ((flags & CLS_META) != 0);
6387 if (baseMethods.size() > 0) {
6388 Result +=
"(const struct _method_list_t *)&";
6390 Result +=
"_OBJC_$_CLASS_METHODS_";
6392 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6393 Result += ClassName;
6397 Result +=
"0, \n\t";
6399 if (!metaclass && baseProtocols.size() > 0) {
6400 Result +=
"(const struct _objc_protocol_list *)&";
6401 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6405 Result +=
"0, \n\t";
6407 if (!metaclass && ivars.size() > 0) {
6408 Result +=
"(const struct _ivar_list_t *)&";
6409 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6413 Result +=
"0, \n\t";
6416 Result +=
"0, \n\t";
6417 if (!metaclass && Properties.size() > 0) {
6418 Result +=
"(const struct _prop_list_t *)&";
6419 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6428static void Write_class_t(
ASTContext *Context, std::string &Result,
6442 if (metaclass && rootClass) {
6445 Result +=
"extern \"C\" ";
6447 Result +=
"__declspec(dllexport) ";
6449 Result +=
"__declspec(dllimport) ";
6451 Result +=
"struct _class_t OBJC_CLASS_$_";
6459 Result +=
"extern \"C\" ";
6461 Result +=
"__declspec(dllexport) ";
6463 Result +=
"__declspec(dllimport) ";
6465 Result +=
"struct _class_t ";
6470 if (metaclass && RootClass != SuperClass) {
6471 Result +=
"extern \"C\" ";
6473 Result +=
"__declspec(dllexport) ";
6475 Result +=
"__declspec(dllimport) ";
6477 Result +=
"struct _class_t ";
6484 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6486 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6490 Result +=
"0, // &"; Result += VarName;
6493 Result +=
"0, // &"; Result += VarName;
6498 Result +=
"0, // &"; Result += VarName;
6506 Result +=
"0, // &OBJC_METACLASS_$_";
6510 Result +=
"0, // &"; Result += VarName;
6517 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6518 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6520 Result +=
"&_OBJC_METACLASS_RO_$_";
6522 Result +=
"&_OBJC_CLASS_RO_$_";
6524 Result +=
",\n};\n";
6534 Result +=
"static void OBJC_CLASS_SETUP_$_";
6536 Result +=
"(void ) {\n";
6538 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6542 Result +=
".superclass = ";
6544 Result +=
"&OBJC_CLASS_$_";
6546 Result +=
"&OBJC_METACLASS_$_";
6551 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6554 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6559 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6564 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6568static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6569 std::string &Result,
6576 StringRef CatName = CatDecl->
getName();
6577 StringRef ClassName = ClassDecl->
getName();
6581 Result +=
"extern \"C\" ";
6583 Result +=
"__declspec(dllexport) ";
6585 Result +=
"__declspec(dllimport) ";
6587 Result +=
"struct _class_t ";
6588 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6591 Result +=
"\nstatic struct _category_t ";
6592 Result +=
"_OBJC_$_CATEGORY_";
6593 Result += ClassName; Result +=
"_$_"; Result += CatName;
6594 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6596 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6597 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6599 if (InstanceMethods.size() > 0) {
6600 Result +=
"\t(const struct _method_list_t *)&";
6601 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6602 Result += ClassName; Result +=
"_$_"; Result += CatName;
6608 if (ClassMethods.size() > 0) {
6609 Result +=
"\t(const struct _method_list_t *)&";
6610 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6611 Result += ClassName; Result +=
"_$_"; Result += CatName;
6617 if (RefedProtocols.size() > 0) {
6618 Result +=
"\t(const struct _protocol_list_t *)&";
6619 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6620 Result += ClassName; Result +=
"_$_"; Result += CatName;
6626 if (ClassProperties.size() > 0) {
6627 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6628 Result += ClassName; Result +=
"_$_"; Result += CatName;
6637 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6641 Result +=
"(void ) {\n";
6642 Result +=
"\t_OBJC_$_CATEGORY_";
6646 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6650static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6654 StringRef ProtocolName) {
6655 if (Methods.size() == 0)
6658 Result +=
"\nstatic const char *";
6659 Result += VarName; Result += ProtocolName;
6660 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6662 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6664 std::string MethodTypeString =
6665 Context->getObjCEncodingForMethodDecl(MD,
true);
6666 std::string QuoteMethodTypeString;
6667 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6668 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6677static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6679 std::string &Result,
6694 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6696 if (Context->getLangOpts().MicrosoftExt)
6697 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6699 if (!Context->getLangOpts().MicrosoftExt ||
6702 Result +=
"extern \"C\" unsigned long int ";
6704 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6705 if (Ivars[i]->isBitField())
6706 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6708 WriteInternalIvarName(CDecl, IvarDecl, Result);
6709 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6711 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6713 if (Ivars[i]->isBitField()) {
6715 SKIP_BITFIELDS(i , e, Ivars);
6720static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6725 if (OriginalIvars.size() > 0) {
6726 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6731 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6732 if (OriginalIvars[i]->isBitField()) {
6733 Ivars.push_back(OriginalIvars[i]);
6735 SKIP_BITFIELDS(i , e, OriginalIvars);
6738 Ivars.push_back(OriginalIvars[i]);
6741 Result +=
"\nstatic ";
6742 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6743 Result +=
" "; Result += VarName;
6745 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6746 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6747 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6748 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6754 Result +=
"(unsigned long int *)&";
6755 if (Ivars[i]->isBitField())
6756 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6758 WriteInternalIvarName(CDecl, IvarDecl, Result);
6762 if (Ivars[i]->isBitField())
6763 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6765 Result += IvarDecl->
getName();
6770 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6772 std::string IvarTypeString, QuoteIvarTypeString;
6773 Context->getObjCEncodingForType(IVQT, IvarTypeString,
6775 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6776 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6780 unsigned Align = Context->getTypeAlign(IVQT)/8;
6781 Align = llvm::Log2_32(Align);
6782 Result += llvm::utostr(Align); Result +=
", ";
6784 Result += llvm::utostr(
Size.getQuantity());
6795void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6796 std::string &Result) {
6801 WriteModernMetadataDeclarations(Context, Result);
6808 RewriteObjCProtocolMetaData(I, Result);
6811 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6812 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6815 OptInstanceMethods.push_back(MD);
6817 InstanceMethods.push_back(MD);
6823 OptClassMethods.push_back(MD);
6825 ClassMethods.push_back(MD);
6828 std::vector<ObjCMethodDecl *> AllMethods;
6829 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6830 AllMethods.push_back(InstanceMethods[i]);
6831 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6832 AllMethods.push_back(ClassMethods[i]);
6833 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6834 AllMethods.push_back(OptInstanceMethods[i]);
6835 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6836 AllMethods.push_back(OptClassMethods[i]);
6838 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6840 "_OBJC_PROTOCOL_METHOD_TYPES_",
6844 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6845 "_OBJC_PROTOCOL_REFS_",
6848 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6849 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6852 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6853 "_OBJC_PROTOCOL_CLASS_METHODS_",
6856 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6857 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6860 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6861 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6867 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
6869 "_OBJC_PROTOCOL_PROPERTIES_",
6874 if (LangOpts.MicrosoftExt)
6875 Result +=
"static ";
6876 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6878 Result +=
" __attribute__ ((used)) = {\n";
6880 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6881 if (SuperProtocols.size() > 0) {
6882 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6887 if (InstanceMethods.size() > 0) {
6888 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6894 if (ClassMethods.size() > 0) {
6895 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6901 if (OptInstanceMethods.size() > 0) {
6902 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6908 if (OptClassMethods.size() > 0) {
6909 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6915 if (ProtocolProperties.size() > 0) {
6916 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6922 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6925 if (AllMethods.size() > 0) {
6926 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6931 Result +=
"\t0\n};\n";
6933 if (LangOpts.MicrosoftExt)
6934 Result +=
"static ";
6935 Result +=
"struct _protocol_t *";
6936 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6942 llvm_unreachable(
"protocol already synthesized");
6950 if (OID->
hasAttr<ObjCExceptionAttr>())
6958 std::string &Result) {
6964 "Legacy implicit interface rewriting not supported in moder abi");
6966 WriteModernMetadataDeclarations(Context, Result);
6972 if (!IVD->getDeclName())
6974 IVars.push_back(IVD);
6977 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
6978 "_OBJC_$_INSTANCE_VARIABLES_",
6989 if (!Prop->getPropertyIvarDecl())
6995 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
6996 InstanceMethods.push_back(Getter);
7000 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7001 InstanceMethods.push_back(Setter);
7004 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7005 "_OBJC_$_INSTANCE_METHODS_",
7010 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7011 "_OBJC_$_CLASS_METHODS_",
7016 std::vector<ObjCProtocolDecl *> RefedProtocols;
7019 E = Protocols.
end();
7021 RefedProtocols.push_back(*I);
7024 RewriteObjCProtocolMetaData(*I, Result);
7027 Write_protocol_list_initializer(Context, Result,
7029 "_OBJC_CLASS_PROTOCOLS_$_",
7035 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7037 "_OBJC_$_PROP_LIST_",
7041 uint32_t flags = CLS_META;
7042 std::string InstanceSize;
7043 std::string InstanceStart;
7047 flags |= OBJC2_CLS_HIDDEN;
7052 InstanceSize =
"sizeof(struct _class_t)";
7053 InstanceStart = InstanceSize;
7054 Write__class_ro_t_initializer(Context, Result, flags,
7055 InstanceStart, InstanceSize,
7060 "_OBJC_METACLASS_RO_$_",
7066 flags |= OBJC2_CLS_HIDDEN;
7069 flags |= CLS_EXCEPTION;
7075 InstanceSize.clear();
7076 InstanceStart.clear();
7077 if (!ObjCSynthesizedStructs.count(CDecl)) {
7079 InstanceStart =
"0";
7082 InstanceSize =
"sizeof(struct ";
7084 InstanceSize +=
"_IMPL)";
7088 RewriteIvarOffsetComputation(IVD, InstanceStart);
7091 InstanceStart = InstanceSize;
7093 Write__class_ro_t_initializer(Context, Result, flags,
7094 InstanceStart, InstanceSize,
7099 "_OBJC_CLASS_RO_$_",
7102 Write_class_t(Context, Result,
7103 "OBJC_METACLASS_$_",
7106 Write_class_t(Context, Result,
7110 if (ImplementationIsNonLazy(IDecl))
7111 DefinedNonLazyClasses.push_back(CDecl);
7114void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7115 int ClsDefCount = ClassImplementation.size();
7118 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7119 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7120 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7121 for (
int i = 0; i < ClsDefCount; i++) {
7124 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7125 Result += CDecl->
getName(); Result +=
",\n";
7130void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7131 int ClsDefCount = ClassImplementation.size();
7132 int CatDefCount = CategoryImplementation.size();
7135 for (
int i = 0; i < ClsDefCount; i++)
7136 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7138 RewriteClassSetupInitHook(Result);
7141 for (
int i = 0; i < CatDefCount; i++)
7142 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7144 RewriteCategorySetupInitHook(Result);
7146 if (ClsDefCount > 0) {
7147 if (LangOpts.MicrosoftExt)
7148 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7149 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7150 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7152 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7153 "regular,no_dead_strip\")))= {\n";
7154 for (
int i = 0; i < ClsDefCount; i++) {
7155 Result +=
"\t&OBJC_CLASS_$_";
7156 Result += ClassImplementation[i]->getNameAsString();
7161 if (!DefinedNonLazyClasses.empty()) {
7162 if (LangOpts.MicrosoftExt)
7163 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7164 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7165 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7166 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7173 if (CatDefCount > 0) {
7174 if (LangOpts.MicrosoftExt)
7175 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7176 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7177 Result += llvm::utostr(CatDefCount); Result +=
"]";
7179 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7180 "regular,no_dead_strip\")))= {\n";
7181 for (
int i = 0; i < CatDefCount; i++) {
7182 Result +=
"\t&_OBJC_$_CATEGORY_";
7184 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7186 Result += CategoryImplementation[i]->getNameAsString();
7192 if (!DefinedNonLazyCategories.empty()) {
7193 if (LangOpts.MicrosoftExt)
7194 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7195 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7196 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7197 Result +=
"\t&_OBJC_$_CATEGORY_";
7199 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7201 Result += DefinedNonLazyCategories[i]->getNameAsString();
7208void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7209 if (LangOpts.MicrosoftExt)
7210 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7212 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7214 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7220 std::string &Result) {
7221 WriteModernMetadataDeclarations(Context, Result);
7228 FullCategoryName +=
"_$_";
7239 if (!Prop->getPropertyIvarDecl())
7245 InstanceMethods.push_back(Getter);
7249 InstanceMethods.push_back(Setter);
7252 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7253 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7254 FullCategoryName,
true);
7258 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7259 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7260 FullCategoryName,
true);
7268 RewriteObjCProtocolMetaData(I, Result);
7270 Write_protocol_list_initializer(Context, Result,
7272 "_OBJC_CATEGORY_PROTOCOLS_$_",
7278 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7280 "_OBJC_$_PROP_LIST_",
7283 Write_category_t(*
this, Context, Result,
7292 if (ImplementationIsNonLazy(IDecl))
7293 DefinedNonLazyCategories.push_back(CDecl);
7296void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7297 int CatDefCount = CategoryImplementation.size();
7300 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7301 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7302 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7303 for (
int i = 0; i < CatDefCount; i++) {
7307 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7308 Result += ClassDecl->
getName();
7318template<
typename MethodIterator>
7319void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7320 MethodIterator MethodEnd,
7321 bool IsInstanceMethod,
7323 StringRef ClassName,
7324 std::string &Result) {
7325 if (MethodBegin == MethodEnd)
return;
7327 if (!objc_impl_method) {
7334 Result +=
"\nstruct _objc_method {\n";
7335 Result +=
"\tSEL _cmd;\n";
7336 Result +=
"\tchar *method_types;\n";
7337 Result +=
"\tvoid *_imp;\n";
7340 objc_impl_method =
true;
7351 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7353 if (LangOpts.MicrosoftExt) {
7354 if (IsInstanceMethod)
7355 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7357 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7359 Result +=
"static struct {\n";
7360 Result +=
"\tstruct _objc_method_list *next_method;\n";
7361 Result +=
"\tint method_count;\n";
7362 Result +=
"\tstruct _objc_method method_list[";
7363 Result += utostr(NumMethods);
7364 Result +=
"];\n} _OBJC_";
7367 Result +=
"_METHODS_";
7368 Result += ClassName;
7369 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7371 Result +=
"_meth\")))= ";
7372 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7374 Result +=
"\t,{{(SEL)\"";
7375 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7376 std::string MethodTypeString;
7377 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7379 Result += MethodTypeString;
7380 Result +=
"\", (void *)";
7381 Result += MethodInternalNames[*MethodBegin];
7383 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7384 Result +=
"\t ,{(SEL)\"";
7385 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7386 std::string MethodTypeString;
7387 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7389 Result += MethodTypeString;
7390 Result +=
"\", (void *)";
7391 Result += MethodInternalNames[*MethodBegin];
7394 Result +=
"\t }\n};\n";
7403 DisableReplaceStmtScope S(*
this);
7404 BaseExpr =
cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7410 Expr *Replacement = IV;
7415 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7420 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7423 std::string IvarOffsetName;
7425 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7427 WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
7429 ReferencedIvars[clsDeclared].insert(D);
7433 Context->getPointerType(Context->CharTy),
7437 SourceLocation(), &Context->Idents.get(IvarOffsetName),
7438 Context->UnsignedLongTy,
nullptr,
7441 DeclRefExpr(*Context, NewVD,
false, Context->UnsignedLongTy,
7453 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7465 std::string RecName = std::string(CDecl->
getName());
7469 SourceLocation(), &Context->Idents.get(RecName));
7471 Context->getPointerType(Context->getCanonicalTagType(RD));
7472 unsigned UnsignedIntSize =
7473 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
7475 llvm::APInt(UnsignedIntSize, 0),
7476 Context->UnsignedIntTy, SourceLocation());
7477 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7488 IvarT = Context->getDecltypeType(ME, ME->
getType());
7491 convertObjCTypeToCStyleType(IvarT);
7492 QualType castT = Context->getPointerType(IvarT);
7494 castExpr = NoTypeInfoCStyleCastExpr(Context,
7502 PE =
new (Context)
ParenExpr(OldRange.getBegin(),
7523 ReplaceStmtWithRange(IV, Replacement, OldRange);
Defines the Diagnostic-related interfaces.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
Defines the SourceManager interface.
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getObjCClassType() const
Represents the Objective-C Class type.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
FullSourceLoc getFullLoc(SourceLocation Loc) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
SelectorTable & Selectors
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getObjCIdType() const
Represents the Objective-CC id type.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Represents a member of a struct/union/class.
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
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".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
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]).
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
ExprIterator arg_iterator
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
SourceLocation getEndLoc() const
ConditionalOperator - The ?
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()
DeclGroupRef::iterator decl_iterator
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
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
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.
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.
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
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 ...
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes an C or C++ initializer list.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static std::string Stringify(StringRef Str, bool Charify=false)
Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...
Represents a linkage specification.
SourceLocation getBeginLoc() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on.
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.
const CompoundStmt * getSynchBody() const
SourceLocation getAtSynchronizedLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents Objective-C's @throw statement.
const Expr * getThrowExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
Represents Objective-C's @try ... @catch ... @finally statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
SourceLocation getBeginLoc() const LLVM_READONLY
const Stmt * getTryBody() const
Retrieve the @try body.
SourceLocation getAtTryLoc() const
Retrieve the location of the @ in the @try.
catch_range catch_stmts()
Represents Objective-C's @autoreleasepool Statement.
SourceLocation getAtLoc() const
const Stmt * getSubStmt() const
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.
SourceLocation getForLoc() const
SourceLocation getRParenLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
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
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
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.
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
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
@ SuperInstance
The receiver is the instance of the superclass object.
@ Instance
The receiver is an object instance.
@ SuperClass
The receiver is a superclass.
@ Class
The receiver is a class.
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.
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 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.
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
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
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.
static bool isRewritable(SourceLocation Loc)
isRewritable - Return true if this location is a raw file location, which is rewritable.
std::string getAsString() const
Derive the full selector name (e.g.
bool isValid() const
Return true if this is a valid SourceLocation object.
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
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.
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.
bool isBlockPointerType() const
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
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.
RecordDecl * castAsRecordDecl() const
bool isObjCQualifiedInterfaceType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isRealFloatingType() const
Floating point categories.
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Base class for declarations which introduce a typedef-name.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
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.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
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::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ CF
Indicates that the tracked object is a CF object.
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...
@ ICIS_NoInit
No in-class initializer.
@ 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].
const FunctionProtoType * T
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
@ Struct
The "struct" keyword.
CastKind
CastKind - The kind of operation required for a conversion.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
CLINKAGE int printf(__constant const char *st,...) __attribute__((format(printf
An element in an Objective-C dictionary literal.
Expr * Value
The value of the dictionary element.
Expr * Key
The key for the dictionary element.
Describes how types, statements, expressions, and declarations should be printed.