PageRenderTime 75ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 1ms

/contrib/llvm/tools/clang/lib/Rewrite/RewriteModernObjC.cpp

https://bitbucket.org/freebsd/freebsd-head/
C++ | 7543 lines | 5919 code | 738 blank | 886 comment | 1041 complexity | 2ed2046794fc9451031af33af51c7ef3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. //===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Hacks and fun related to the code rewriter.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/Rewrite/ASTConsumers.h"
  14. #include "clang/Rewrite/Rewriter.h"
  15. #include "clang/AST/AST.h"
  16. #include "clang/AST/ASTConsumer.h"
  17. #include "clang/AST/ParentMap.h"
  18. #include "clang/Basic/SourceManager.h"
  19. #include "clang/Basic/IdentifierTable.h"
  20. #include "clang/Basic/Diagnostic.h"
  21. #include "clang/Lex/Lexer.h"
  22. #include "llvm/Support/MemoryBuffer.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. #include "llvm/ADT/StringExtras.h"
  25. #include "llvm/ADT/SmallPtrSet.h"
  26. #include "llvm/ADT/OwningPtr.h"
  27. #include "llvm/ADT/DenseSet.h"
  28. using namespace clang;
  29. using llvm::utostr;
  30. namespace {
  31. class RewriteModernObjC : public ASTConsumer {
  32. protected:
  33. enum {
  34. BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)),
  35. block, ... */
  36. BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
  37. BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the
  38. __block variable */
  39. BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy
  40. helpers */
  41. BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose
  42. support routines */
  43. BLOCK_BYREF_CURRENT_MAX = 256
  44. };
  45. enum {
  46. BLOCK_NEEDS_FREE = (1 << 24),
  47. BLOCK_HAS_COPY_DISPOSE = (1 << 25),
  48. BLOCK_HAS_CXX_OBJ = (1 << 26),
  49. BLOCK_IS_GC = (1 << 27),
  50. BLOCK_IS_GLOBAL = (1 << 28),
  51. BLOCK_HAS_DESCRIPTOR = (1 << 29)
  52. };
  53. static const int OBJC_ABI_VERSION = 7;
  54. Rewriter Rewrite;
  55. DiagnosticsEngine &Diags;
  56. const LangOptions &LangOpts;
  57. ASTContext *Context;
  58. SourceManager *SM;
  59. TranslationUnitDecl *TUDecl;
  60. FileID MainFileID;
  61. const char *MainFileStart, *MainFileEnd;
  62. Stmt *CurrentBody;
  63. ParentMap *PropParentMap; // created lazily.
  64. std::string InFileName;
  65. raw_ostream* OutFile;
  66. std::string Preamble;
  67. TypeDecl *ProtocolTypeDecl;
  68. VarDecl *GlobalVarDecl;
  69. Expr *GlobalConstructionExp;
  70. unsigned RewriteFailedDiag;
  71. unsigned GlobalBlockRewriteFailedDiag;
  72. // ObjC string constant support.
  73. unsigned NumObjCStringLiterals;
  74. VarDecl *ConstantStringClassReference;
  75. RecordDecl *NSStringRecord;
  76. // ObjC foreach break/continue generation support.
  77. int BcLabelCount;
  78. unsigned TryFinallyContainsReturnDiag;
  79. // Needed for super.
  80. ObjCMethodDecl *CurMethodDef;
  81. RecordDecl *SuperStructDecl;
  82. RecordDecl *ConstantStringDecl;
  83. FunctionDecl *MsgSendFunctionDecl;
  84. FunctionDecl *MsgSendSuperFunctionDecl;
  85. FunctionDecl *MsgSendStretFunctionDecl;
  86. FunctionDecl *MsgSendSuperStretFunctionDecl;
  87. FunctionDecl *MsgSendFpretFunctionDecl;
  88. FunctionDecl *GetClassFunctionDecl;
  89. FunctionDecl *GetMetaClassFunctionDecl;
  90. FunctionDecl *GetSuperClassFunctionDecl;
  91. FunctionDecl *SelGetUidFunctionDecl;
  92. FunctionDecl *CFStringFunctionDecl;
  93. FunctionDecl *SuperContructorFunctionDecl;
  94. FunctionDecl *CurFunctionDef;
  95. /* Misc. containers needed for meta-data rewrite. */
  96. SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
  97. SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
  98. llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
  99. llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
  100. llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
  101. llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
  102. SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
  103. /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
  104. SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
  105. /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
  106. llvm::SmallVector<ObjCCategoryDecl*, 8> DefinedNonLazyCategories;
  107. SmallVector<Stmt *, 32> Stmts;
  108. SmallVector<int, 8> ObjCBcLabelNo;
  109. // Remember all the @protocol(<expr>) expressions.
  110. llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
  111. llvm::DenseSet<uint64_t> CopyDestroyCache;
  112. // Block expressions.
  113. SmallVector<BlockExpr *, 32> Blocks;
  114. SmallVector<int, 32> InnerDeclRefsCount;
  115. SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
  116. SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
  117. // Block related declarations.
  118. SmallVector<ValueDecl *, 8> BlockByCopyDecls;
  119. llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
  120. SmallVector<ValueDecl *, 8> BlockByRefDecls;
  121. llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
  122. llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
  123. llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
  124. llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
  125. llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
  126. llvm::DenseMap<ObjCInterfaceDecl *,
  127. llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
  128. // This maps an original source AST to it's rewritten form. This allows
  129. // us to avoid rewriting the same node twice (which is very uncommon).
  130. // This is needed to support some of the exotic property rewriting.
  131. llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
  132. // Needed for header files being rewritten
  133. bool IsHeader;
  134. bool SilenceRewriteMacroWarning;
  135. bool objc_impl_method;
  136. bool DisableReplaceStmt;
  137. class DisableReplaceStmtScope {
  138. RewriteModernObjC &R;
  139. bool SavedValue;
  140. public:
  141. DisableReplaceStmtScope(RewriteModernObjC &R)
  142. : R(R), SavedValue(R.DisableReplaceStmt) {
  143. R.DisableReplaceStmt = true;
  144. }
  145. ~DisableReplaceStmtScope() {
  146. R.DisableReplaceStmt = SavedValue;
  147. }
  148. };
  149. void InitializeCommon(ASTContext &context);
  150. public:
  151. llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
  152. // Top Level Driver code.
  153. virtual bool HandleTopLevelDecl(DeclGroupRef D) {
  154. for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
  155. if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
  156. if (!Class->isThisDeclarationADefinition()) {
  157. RewriteForwardClassDecl(D);
  158. break;
  159. } else {
  160. // Keep track of all interface declarations seen.
  161. ObjCInterfacesSeen.push_back(Class);
  162. break;
  163. }
  164. }
  165. if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
  166. if (!Proto->isThisDeclarationADefinition()) {
  167. RewriteForwardProtocolDecl(D);
  168. break;
  169. }
  170. }
  171. HandleTopLevelSingleDecl(*I);
  172. }
  173. return true;
  174. }
  175. void HandleTopLevelSingleDecl(Decl *D);
  176. void HandleDeclInMainFile(Decl *D);
  177. RewriteModernObjC(std::string inFile, raw_ostream *OS,
  178. DiagnosticsEngine &D, const LangOptions &LOpts,
  179. bool silenceMacroWarn);
  180. ~RewriteModernObjC() {}
  181. virtual void HandleTranslationUnit(ASTContext &C);
  182. void ReplaceStmt(Stmt *Old, Stmt *New) {
  183. Stmt *ReplacingStmt = ReplacedNodes[Old];
  184. if (ReplacingStmt)
  185. return; // We can't rewrite the same node twice.
  186. if (DisableReplaceStmt)
  187. return;
  188. // If replacement succeeded or warning disabled return with no warning.
  189. if (!Rewrite.ReplaceStmt(Old, New)) {
  190. ReplacedNodes[Old] = New;
  191. return;
  192. }
  193. if (SilenceRewriteMacroWarning)
  194. return;
  195. Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
  196. << Old->getSourceRange();
  197. }
  198. void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
  199. if (DisableReplaceStmt)
  200. return;
  201. // Measure the old text.
  202. int Size = Rewrite.getRangeSize(SrcRange);
  203. if (Size == -1) {
  204. Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
  205. << Old->getSourceRange();
  206. return;
  207. }
  208. // Get the new text.
  209. std::string SStr;
  210. llvm::raw_string_ostream S(SStr);
  211. New->printPretty(S, 0, PrintingPolicy(LangOpts));
  212. const std::string &Str = S.str();
  213. // If replacement succeeded or warning disabled return with no warning.
  214. if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
  215. ReplacedNodes[Old] = New;
  216. return;
  217. }
  218. if (SilenceRewriteMacroWarning)
  219. return;
  220. Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
  221. << Old->getSourceRange();
  222. }
  223. void InsertText(SourceLocation Loc, StringRef Str,
  224. bool InsertAfter = true) {
  225. // If insertion succeeded or warning disabled return with no warning.
  226. if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
  227. SilenceRewriteMacroWarning)
  228. return;
  229. Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
  230. }
  231. void ReplaceText(SourceLocation Start, unsigned OrigLength,
  232. StringRef Str) {
  233. // If removal succeeded or warning disabled return with no warning.
  234. if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
  235. SilenceRewriteMacroWarning)
  236. return;
  237. Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
  238. }
  239. // Syntactic Rewriting.
  240. void RewriteRecordBody(RecordDecl *RD);
  241. void RewriteInclude();
  242. void RewriteForwardClassDecl(DeclGroupRef D);
  243. void RewriteForwardClassDecl(const llvm::SmallVector<Decl*, 8> &DG);
  244. void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
  245. const std::string &typedefString);
  246. void RewriteImplementations();
  247. void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
  248. ObjCImplementationDecl *IMD,
  249. ObjCCategoryImplDecl *CID);
  250. void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
  251. void RewriteImplementationDecl(Decl *Dcl);
  252. void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
  253. ObjCMethodDecl *MDecl, std::string &ResultStr);
  254. void RewriteTypeIntoString(QualType T, std::string &ResultStr,
  255. const FunctionType *&FPRetType);
  256. void RewriteByRefString(std::string &ResultStr, const std::string &Name,
  257. ValueDecl *VD, bool def=false);
  258. void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
  259. void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
  260. void RewriteForwardProtocolDecl(DeclGroupRef D);
  261. void RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG);
  262. void RewriteMethodDeclaration(ObjCMethodDecl *Method);
  263. void RewriteProperty(ObjCPropertyDecl *prop);
  264. void RewriteFunctionDecl(FunctionDecl *FD);
  265. void RewriteBlockPointerType(std::string& Str, QualType Type);
  266. void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
  267. void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
  268. void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
  269. void RewriteTypeOfDecl(VarDecl *VD);
  270. void RewriteObjCQualifiedInterfaceTypes(Expr *E);
  271. std::string getIvarAccessString(ObjCIvarDecl *D);
  272. // Expression Rewriting.
  273. Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
  274. Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
  275. Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
  276. Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
  277. Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
  278. Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
  279. Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
  280. Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
  281. Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
  282. Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
  283. Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
  284. Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
  285. Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
  286. Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
  287. Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
  288. Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
  289. Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
  290. SourceLocation OrigEnd);
  291. Stmt *RewriteBreakStmt(BreakStmt *S);
  292. Stmt *RewriteContinueStmt(ContinueStmt *S);
  293. void RewriteCastExpr(CStyleCastExpr *CE);
  294. void RewriteImplicitCastObjCExpr(CastExpr *IE);
  295. void RewriteLinkageSpec(LinkageSpecDecl *LSD);
  296. // Block rewriting.
  297. void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
  298. // Block specific rewrite rules.
  299. void RewriteBlockPointerDecl(NamedDecl *VD);
  300. void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl);
  301. Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
  302. Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
  303. void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
  304. void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
  305. std::string &Result);
  306. void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
  307. bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag,
  308. bool &IsNamedDefinition);
  309. void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl,
  310. std::string &Result);
  311. bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
  312. void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
  313. std::string &Result);
  314. virtual void Initialize(ASTContext &context);
  315. // Misc. AST transformation routines. Sometimes they end up calling
  316. // rewriting routines on the new ASTs.
  317. CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
  318. Expr **args, unsigned nargs,
  319. SourceLocation StartLoc=SourceLocation(),
  320. SourceLocation EndLoc=SourceLocation());
  321. Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
  322. QualType msgSendType,
  323. QualType returnType,
  324. SmallVectorImpl<QualType> &ArgTypes,
  325. SmallVectorImpl<Expr*> &MsgExprs,
  326. ObjCMethodDecl *Method);
  327. Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
  328. SourceLocation StartLoc=SourceLocation(),
  329. SourceLocation EndLoc=SourceLocation());
  330. void SynthCountByEnumWithState(std::string &buf);
  331. void SynthMsgSendFunctionDecl();
  332. void SynthMsgSendSuperFunctionDecl();
  333. void SynthMsgSendStretFunctionDecl();
  334. void SynthMsgSendFpretFunctionDecl();
  335. void SynthMsgSendSuperStretFunctionDecl();
  336. void SynthGetClassFunctionDecl();
  337. void SynthGetMetaClassFunctionDecl();
  338. void SynthGetSuperClassFunctionDecl();
  339. void SynthSelGetUidFunctionDecl();
  340. void SynthSuperContructorFunctionDecl();
  341. // Rewriting metadata
  342. template<typename MethodIterator>
  343. void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
  344. MethodIterator MethodEnd,
  345. bool IsInstanceMethod,
  346. StringRef prefix,
  347. StringRef ClassName,
  348. std::string &Result);
  349. void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
  350. std::string &Result);
  351. void RewriteObjCProtocolListMetaData(
  352. const ObjCList<ObjCProtocolDecl> &Prots,
  353. StringRef prefix, StringRef ClassName, std::string &Result);
  354. void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
  355. std::string &Result);
  356. void RewriteClassSetupInitHook(std::string &Result);
  357. void RewriteMetaDataIntoBuffer(std::string &Result);
  358. void WriteImageInfo(std::string &Result);
  359. void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
  360. std::string &Result);
  361. void RewriteCategorySetupInitHook(std::string &Result);
  362. // Rewriting ivar
  363. void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
  364. std::string &Result);
  365. Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
  366. std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
  367. std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
  368. StringRef funcName, std::string Tag);
  369. std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
  370. StringRef funcName, std::string Tag);
  371. std::string SynthesizeBlockImpl(BlockExpr *CE,
  372. std::string Tag, std::string Desc);
  373. std::string SynthesizeBlockDescriptor(std::string DescTag,
  374. std::string ImplTag,
  375. int i, StringRef funcName,
  376. unsigned hasCopy);
  377. Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
  378. void SynthesizeBlockLiterals(SourceLocation FunLocStart,
  379. StringRef FunName);
  380. FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
  381. Stmt *SynthBlockInitExpr(BlockExpr *Exp,
  382. const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs);
  383. // Misc. helper routines.
  384. QualType getProtocolType();
  385. void WarnAboutReturnGotoStmts(Stmt *S);
  386. void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
  387. void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
  388. void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
  389. bool IsDeclStmtInForeachHeader(DeclStmt *DS);
  390. void CollectBlockDeclRefInfo(BlockExpr *Exp);
  391. void GetBlockDeclRefExprs(Stmt *S);
  392. void GetInnerBlockDeclRefExprs(Stmt *S,
  393. SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
  394. llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
  395. // We avoid calling Type::isBlockPointerType(), since it operates on the
  396. // canonical type. We only care if the top-level type is a closure pointer.
  397. bool isTopLevelBlockPointerType(QualType T) {
  398. return isa<BlockPointerType>(T);
  399. }
  400. /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
  401. /// to a function pointer type and upon success, returns true; false
  402. /// otherwise.
  403. bool convertBlockPointerToFunctionPointer(QualType &T) {
  404. if (isTopLevelBlockPointerType(T)) {
  405. const BlockPointerType *BPT = T->getAs<BlockPointerType>();
  406. T = Context->getPointerType(BPT->getPointeeType());
  407. return true;
  408. }
  409. return false;
  410. }
  411. bool convertObjCTypeToCStyleType(QualType &T);
  412. bool needToScanForQualifiers(QualType T);
  413. QualType getSuperStructType();
  414. QualType getConstantStringStructType();
  415. QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
  416. bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
  417. void convertToUnqualifiedObjCType(QualType &T) {
  418. if (T->isObjCQualifiedIdType()) {
  419. bool isConst = T.isConstQualified();
  420. T = isConst ? Context->getObjCIdType().withConst()
  421. : Context->getObjCIdType();
  422. }
  423. else if (T->isObjCQualifiedClassType())
  424. T = Context->getObjCClassType();
  425. else if (T->isObjCObjectPointerType() &&
  426. T->getPointeeType()->isObjCQualifiedInterfaceType()) {
  427. if (const ObjCObjectPointerType * OBJPT =
  428. T->getAsObjCInterfacePointerType()) {
  429. const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
  430. T = QualType(IFaceT, 0);
  431. T = Context->getPointerType(T);
  432. }
  433. }
  434. }
  435. // FIXME: This predicate seems like it would be useful to add to ASTContext.
  436. bool isObjCType(QualType T) {
  437. if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
  438. return false;
  439. QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
  440. if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
  441. OCT == Context->getCanonicalType(Context->getObjCClassType()))
  442. return true;
  443. if (const PointerType *PT = OCT->getAs<PointerType>()) {
  444. if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
  445. PT->getPointeeType()->isObjCQualifiedIdType())
  446. return true;
  447. }
  448. return false;
  449. }
  450. bool PointerTypeTakesAnyBlockArguments(QualType QT);
  451. bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
  452. void GetExtentOfArgList(const char *Name, const char *&LParen,
  453. const char *&RParen);
  454. void QuoteDoublequotes(std::string &From, std::string &To) {
  455. for (unsigned i = 0; i < From.length(); i++) {
  456. if (From[i] == '"')
  457. To += "\\\"";
  458. else
  459. To += From[i];
  460. }
  461. }
  462. QualType getSimpleFunctionType(QualType result,
  463. const QualType *args,
  464. unsigned numArgs,
  465. bool variadic = false) {
  466. if (result == Context->getObjCInstanceType())
  467. result = Context->getObjCIdType();
  468. FunctionProtoType::ExtProtoInfo fpi;
  469. fpi.Variadic = variadic;
  470. return Context->getFunctionType(result, args, numArgs, fpi);
  471. }
  472. // Helper function: create a CStyleCastExpr with trivial type source info.
  473. CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
  474. CastKind Kind, Expr *E) {
  475. TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
  476. return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
  477. SourceLocation(), SourceLocation());
  478. }
  479. bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
  480. IdentifierInfo* II = &Context->Idents.get("load");
  481. Selector LoadSel = Context->Selectors.getSelector(0, &II);
  482. return OD->getClassMethod(LoadSel) != 0;
  483. }
  484. };
  485. }
  486. void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
  487. NamedDecl *D) {
  488. if (const FunctionProtoType *fproto
  489. = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
  490. for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
  491. E = fproto->arg_type_end(); I && (I != E); ++I)
  492. if (isTopLevelBlockPointerType(*I)) {
  493. // All the args are checked/rewritten. Don't call twice!
  494. RewriteBlockPointerDecl(D);
  495. break;
  496. }
  497. }
  498. }
  499. void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
  500. const PointerType *PT = funcType->getAs<PointerType>();
  501. if (PT && PointerTypeTakesAnyBlockArguments(funcType))
  502. RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
  503. }
  504. static bool IsHeaderFile(const std::string &Filename) {
  505. std::string::size_type DotPos = Filename.rfind('.');
  506. if (DotPos == std::string::npos) {
  507. // no file extension
  508. return false;
  509. }
  510. std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
  511. // C header: .h
  512. // C++ header: .hh or .H;
  513. return Ext == "h" || Ext == "hh" || Ext == "H";
  514. }
  515. RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
  516. DiagnosticsEngine &D, const LangOptions &LOpts,
  517. bool silenceMacroWarn)
  518. : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
  519. SilenceRewriteMacroWarning(silenceMacroWarn) {
  520. IsHeader = IsHeaderFile(inFile);
  521. RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
  522. "rewriting sub-expression within a macro (may not be correct)");
  523. // FIXME. This should be an error. But if block is not called, it is OK. And it
  524. // may break including some headers.
  525. GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
  526. "rewriting block literal declared in global scope is not implemented");
  527. TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
  528. DiagnosticsEngine::Warning,
  529. "rewriter doesn't support user-specified control flow semantics "
  530. "for @try/@finally (code may not execute properly)");
  531. }
  532. ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile,
  533. raw_ostream* OS,
  534. DiagnosticsEngine &Diags,
  535. const LangOptions &LOpts,
  536. bool SilenceRewriteMacroWarning) {
  537. return new RewriteModernObjC(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
  538. }
  539. void RewriteModernObjC::InitializeCommon(ASTContext &context) {
  540. Context = &context;
  541. SM = &Context->getSourceManager();
  542. TUDecl = Context->getTranslationUnitDecl();
  543. MsgSendFunctionDecl = 0;
  544. MsgSendSuperFunctionDecl = 0;
  545. MsgSendStretFunctionDecl = 0;
  546. MsgSendSuperStretFunctionDecl = 0;
  547. MsgSendFpretFunctionDecl = 0;
  548. GetClassFunctionDecl = 0;
  549. GetMetaClassFunctionDecl = 0;
  550. GetSuperClassFunctionDecl = 0;
  551. SelGetUidFunctionDecl = 0;
  552. CFStringFunctionDecl = 0;
  553. ConstantStringClassReference = 0;
  554. NSStringRecord = 0;
  555. CurMethodDef = 0;
  556. CurFunctionDef = 0;
  557. GlobalVarDecl = 0;
  558. GlobalConstructionExp = 0;
  559. SuperStructDecl = 0;
  560. ProtocolTypeDecl = 0;
  561. ConstantStringDecl = 0;
  562. BcLabelCount = 0;
  563. SuperContructorFunctionDecl = 0;
  564. NumObjCStringLiterals = 0;
  565. PropParentMap = 0;
  566. CurrentBody = 0;
  567. DisableReplaceStmt = false;
  568. objc_impl_method = false;
  569. // Get the ID and start/end of the main file.
  570. MainFileID = SM->getMainFileID();
  571. const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
  572. MainFileStart = MainBuf->getBufferStart();
  573. MainFileEnd = MainBuf->getBufferEnd();
  574. Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
  575. }
  576. //===----------------------------------------------------------------------===//
  577. // Top Level Driver Code
  578. //===----------------------------------------------------------------------===//
  579. void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
  580. if (Diags.hasErrorOccurred())
  581. return;
  582. // Two cases: either the decl could be in the main file, or it could be in a
  583. // #included file. If the former, rewrite it now. If the later, check to see
  584. // if we rewrote the #include/#import.
  585. SourceLocation Loc = D->getLocation();
  586. Loc = SM->getExpansionLoc(Loc);
  587. // If this is for a builtin, ignore it.
  588. if (Loc.isInvalid()) return;
  589. // Look for built-in declarations that we need to refer during the rewrite.
  590. if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
  591. RewriteFunctionDecl(FD);
  592. } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
  593. // declared in <Foundation/NSString.h>
  594. if (FVD->getName() == "_NSConstantStringClassReference") {
  595. ConstantStringClassReference = FVD;
  596. return;
  597. }
  598. } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
  599. RewriteCategoryDecl(CD);
  600. } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
  601. if (PD->isThisDeclarationADefinition())
  602. RewriteProtocolDecl(PD);
  603. } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
  604. // FIXME. This will not work in all situations and leaving it out
  605. // is harmless.
  606. // RewriteLinkageSpec(LSD);
  607. // Recurse into linkage specifications
  608. for (DeclContext::decl_iterator DI = LSD->decls_begin(),
  609. DIEnd = LSD->decls_end();
  610. DI != DIEnd; ) {
  611. if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
  612. if (!IFace->isThisDeclarationADefinition()) {
  613. SmallVector<Decl *, 8> DG;
  614. SourceLocation StartLoc = IFace->getLocStart();
  615. do {
  616. if (isa<ObjCInterfaceDecl>(*DI) &&
  617. !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
  618. StartLoc == (*DI)->getLocStart())
  619. DG.push_back(*DI);
  620. else
  621. break;
  622. ++DI;
  623. } while (DI != DIEnd);
  624. RewriteForwardClassDecl(DG);
  625. continue;
  626. }
  627. else {
  628. // Keep track of all interface declarations seen.
  629. ObjCInterfacesSeen.push_back(IFace);
  630. ++DI;
  631. continue;
  632. }
  633. }
  634. if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
  635. if (!Proto->isThisDeclarationADefinition()) {
  636. SmallVector<Decl *, 8> DG;
  637. SourceLocation StartLoc = Proto->getLocStart();
  638. do {
  639. if (isa<ObjCProtocolDecl>(*DI) &&
  640. !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
  641. StartLoc == (*DI)->getLocStart())
  642. DG.push_back(*DI);
  643. else
  644. break;
  645. ++DI;
  646. } while (DI != DIEnd);
  647. RewriteForwardProtocolDecl(DG);
  648. continue;
  649. }
  650. }
  651. HandleTopLevelSingleDecl(*DI);
  652. ++DI;
  653. }
  654. }
  655. // If we have a decl in the main file, see if we should rewrite it.
  656. if (SM->isFromMainFile(Loc))
  657. return HandleDeclInMainFile(D);
  658. }
  659. //===----------------------------------------------------------------------===//
  660. // Syntactic (non-AST) Rewriting Code
  661. //===----------------------------------------------------------------------===//
  662. void RewriteModernObjC::RewriteInclude() {
  663. SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
  664. StringRef MainBuf = SM->getBufferData(MainFileID);
  665. const char *MainBufStart = MainBuf.begin();
  666. const char *MainBufEnd = MainBuf.end();
  667. size_t ImportLen = strlen("import");
  668. // Loop over the whole file, looking for includes.
  669. for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
  670. if (*BufPtr == '#') {
  671. if (++BufPtr == MainBufEnd)
  672. return;
  673. while (*BufPtr == ' ' || *BufPtr == '\t')
  674. if (++BufPtr == MainBufEnd)
  675. return;
  676. if (!strncmp(BufPtr, "import", ImportLen)) {
  677. // replace import with include
  678. SourceLocation ImportLoc =
  679. LocStart.getLocWithOffset(BufPtr-MainBufStart);
  680. ReplaceText(ImportLoc, ImportLen, "include");
  681. BufPtr += ImportLen;
  682. }
  683. }
  684. }
  685. }
  686. static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
  687. ObjCIvarDecl *IvarDecl, std::string &Result) {
  688. Result += "OBJC_IVAR_$_";
  689. Result += IDecl->getName();
  690. Result += "$";
  691. Result += IvarDecl->getName();
  692. }
  693. std::string
  694. RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
  695. const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
  696. // Build name of symbol holding ivar offset.
  697. std::string IvarOffsetName;
  698. WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
  699. std::string S = "(*(";
  700. QualType IvarT = D->getType();
  701. if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
  702. RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
  703. RD = RD->getDefinition();
  704. if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
  705. // decltype(((Foo_IMPL*)0)->bar) *
  706. ObjCContainerDecl *CDecl =
  707. dyn_cast<ObjCContainerDecl>(D->getDeclContext());
  708. // ivar in class extensions requires special treatment.
  709. if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
  710. CDecl = CatDecl->getClassInterface();
  711. std::string RecName = CDecl->getName();
  712. RecName += "_IMPL";
  713. RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
  714. SourceLocation(), SourceLocation(),
  715. &Context->Idents.get(RecName.c_str()));
  716. QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
  717. unsigned UnsignedIntSize =
  718. static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
  719. Expr *Zero = IntegerLiteral::Create(*Context,
  720. llvm::APInt(UnsignedIntSize, 0),
  721. Context->UnsignedIntTy, SourceLocation());
  722. Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
  723. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
  724. Zero);
  725. FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
  726. SourceLocation(),
  727. &Context->Idents.get(D->getNameAsString()),
  728. IvarT, 0,
  729. /*BitWidth=*/0, /*Mutable=*/true,
  730. ICIS_NoInit);
  731. MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
  732. FD->getType(), VK_LValue,
  733. OK_Ordinary);
  734. IvarT = Context->getDecltypeType(ME, ME->getType());
  735. }
  736. }
  737. convertObjCTypeToCStyleType(IvarT);
  738. QualType castT = Context->getPointerType(IvarT);
  739. std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
  740. S += TypeString;
  741. S += ")";
  742. // ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
  743. S += "((char *)self + ";
  744. S += IvarOffsetName;
  745. S += "))";
  746. ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
  747. return S;
  748. }
  749. /// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not
  750. /// been found in the class implementation. In this case, it must be synthesized.
  751. static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
  752. ObjCPropertyDecl *PD,
  753. bool getter) {
  754. return getter ? !IMP->getInstanceMethod(PD->getGetterName())
  755. : !IMP->getInstanceMethod(PD->getSetterName());
  756. }
  757. void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
  758. ObjCImplementationDecl *IMD,
  759. ObjCCategoryImplDecl *CID) {
  760. static bool objcGetPropertyDefined = false;
  761. static bool objcSetPropertyDefined = false;
  762. SourceLocation startGetterSetterLoc;
  763. if (PID->getLocStart().isValid()) {
  764. SourceLocation startLoc = PID->getLocStart();
  765. InsertText(startLoc, "// ");
  766. const char *startBuf = SM->getCharacterData(startLoc);
  767. assert((*startBuf == '@') && "bogus @synthesize location");
  768. const char *semiBuf = strchr(startBuf, ';');
  769. assert((*semiBuf == ';') && "@synthesize: can't find ';'");
  770. startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
  771. }
  772. else
  773. startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();
  774. if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
  775. return; // FIXME: is this correct?
  776. // Generate the 'getter' function.
  777. ObjCPropertyDecl *PD = PID->getPropertyDecl();
  778. ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
  779. if (!OID)
  780. return;
  781. unsigned Attributes = PD->getPropertyAttributes();
  782. if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
  783. bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
  784. (Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
  785. ObjCPropertyDecl::OBJC_PR_copy));
  786. std::string Getr;
  787. if (GenGetProperty && !objcGetPropertyDefined) {
  788. objcGetPropertyDefined = true;
  789. // FIXME. Is this attribute correct in all cases?
  790. Getr = "\nextern \"C\" __declspec(dllimport) "
  791. "id objc_getProperty(id, SEL, long, bool);\n";
  792. }
  793. RewriteObjCMethodDecl(OID->getContainingInterface(),
  794. PD->getGetterMethodDecl(), Getr);
  795. Getr += "{ ";
  796. // Synthesize an explicit cast to gain access to the ivar.
  797. // See objc-act.c:objc_synthesize_new_getter() for details.
  798. if (GenGetProperty) {
  799. // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
  800. Getr += "typedef ";
  801. const FunctionType *FPRetType = 0;
  802. RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr,
  803. FPRetType);
  804. Getr += " _TYPE";
  805. if (FPRetType) {
  806. Getr += ")"; // close the precedence "scope" for "*".
  807. // Now, emit the argument types (if any).
  808. if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
  809. Getr += "(";
  810. for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
  811. if (i) Getr += ", ";
  812. std::string ParamStr = FT->getArgType(i).getAsString(
  813. Context->getPrintingPolicy());
  814. Getr += ParamStr;
  815. }
  816. if (FT->isVariadic()) {
  817. if (FT->getNumArgs()) Getr += ", ";
  818. Getr += "...";
  819. }
  820. Getr += ")";
  821. } else
  822. Getr += "()";
  823. }
  824. Getr += ";\n";
  825. Getr += "return (_TYPE)";
  826. Getr += "objc_getProperty(self, _cmd, ";
  827. RewriteIvarOffsetComputation(OID, Getr);
  828. Getr += ", 1)";
  829. }
  830. else
  831. Getr += "return " + getIvarAccessString(OID);
  832. Getr += "; }";
  833. InsertText(startGetterSetterLoc, Getr);
  834. }
  835. if (PD->isReadOnly() ||
  836. !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
  837. return;
  838. // Generate the 'setter' function.
  839. std::string Setr;
  840. bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
  841. ObjCPropertyDecl::OBJC_PR_copy);
  842. if (GenSetProperty && !objcSetPropertyDefined) {
  843. objcSetPropertyDefined = true;
  844. // FIXME. Is this attribute correct in all cases?
  845. Setr = "\nextern \"C\" __declspec(dllimport) "
  846. "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
  847. }
  848. RewriteObjCMethodDecl(OID->getContainingInterface(),
  849. PD->getSetterMethodDecl(), Setr);
  850. Setr += "{ ";
  851. // Synthesize an explicit cast to initialize the ivar.
  852. // See objc-act.c:objc_synthesize_new_setter() for details.
  853. if (GenSetProperty) {
  854. Setr += "objc_setProperty (self, _cmd, ";
  855. RewriteIvarOffsetComputation(OID, Setr);
  856. Setr += ", (id)";
  857. Setr += PD->getName();
  858. Setr += ", ";
  859. if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
  860. Setr += "0, ";
  861. else
  862. Setr += "1, ";
  863. if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
  864. Setr += "1)";
  865. else
  866. Setr += "0)";
  867. }
  868. else {
  869. Setr += getIvarAccessString(OID) + " = ";
  870. Setr += PD->getName();
  871. }
  872. Setr += "; }\n";
  873. InsertText(startGetterSetterLoc, Setr);
  874. }
  875. static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
  876. std::string &typedefString) {
  877. typedefString += "#ifndef _REWRITER_typedef_";
  878. typedefString += ForwardDecl->getNameAsString();
  879. typedefString += "\n";
  880. typedefString += "#define _REWRITER_typedef_";
  881. typedefString += ForwardDecl->getNameAsString();
  882. typedefString += "\n";
  883. typedefString += "typedef struct objc_object ";
  884. typedefString += ForwardDecl->getNameAsString();
  885. // typedef struct { } _objc_exc_Classname;
  886. typedefString += ";\ntypedef struct {} _objc_exc_";
  887. typedefString += ForwardDecl->getNameAsString();
  888. typedefString += ";\n#endif\n";
  889. }
  890. void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
  891. const std::string &typedefString) {
  892. SourceLocation startLoc = ClassDecl->getLocStart();
  893. const char *startBuf = SM->getCharacterData(startLoc);
  894. const char *semiPtr = strchr(startBuf, ';');
  895. // Replace the @class with typedefs corresponding to the classes.
  896. ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
  897. }
  898. void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) {
  899. std::string typedefString;
  900. for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
  901. ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I);
  902. if (I == D.begin()) {
  903. // Translate to typedef's that forward reference structs with the same name
  904. // as the class. As a convenience, we include the original declaration
  905. // as a comment.
  906. typedefString += "// @class ";
  907. typedefString += ForwardDecl->getNameAsString();
  908. typedefString += ";\n";
  909. }
  910. RewriteOneForwardClassDecl(ForwardDecl, typedefString);
  911. }
  912. DeclGroupRef::iterator I = D.begin();
  913. RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
  914. }
  915. void RewriteModernObjC::RewriteForwardClassDecl(
  916. const llvm::SmallVector<Decl*, 8> &D) {
  917. std::string typedefString;
  918. for (unsigned i = 0; i < D.size(); i++) {
  919. ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
  920. if (i == 0) {
  921. typedefString += "// @class ";
  922. typedefString += ForwardDecl->getNameAsString();
  923. typedefString += ";\n";
  924. }
  925. RewriteOneForwardClassDecl(ForwardDecl, typedefString);
  926. }
  927. RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
  928. }
  929. void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
  930. // When method is a synthesized one, such as a getter/setter there is
  931. // nothing to rewrite.
  932. if (Method->isImplicit())
  933. return;
  934. SourceLocation LocStart = Method->getLocStart();
  935. SourceLocation LocEnd = Method->getLocEnd();
  936. if (SM->getExpansionLineNumber(LocEnd) >
  937. SM->getExpansionLineNumber(LocStart)) {
  938. InsertText(LocStart, "#if 0\n");
  939. ReplaceText(LocEnd, 1, ";\n#endif\n");
  940. } else {
  941. InsertText(LocStart, "// ");
  942. }
  943. }
  944. void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) {
  945. SourceLocation Loc = prop->getAtLoc();
  946. ReplaceText(Loc, 0, "// ");
  947. // FIXME: handle properties that are declared across multiple lines.
  948. }
  949. void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
  950. SourceLocation LocStart = CatDecl->getLocStart();
  951. // FIXME: handle category headers that are declared across multiple lines.
  952. if (CatDecl->getIvarRBraceLoc().isValid()) {
  953. ReplaceText(LocStart, 1, "/** ");
  954. ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ ");
  955. }
  956. else {
  957. ReplaceText(LocStart, 0, "// ");
  958. }
  959. for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
  960. E = CatDecl->prop_end(); I != E; ++I)
  961. RewriteProperty(*I);
  962. for (ObjCCategoryDecl::instmeth_iterator
  963. I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
  964. I != E; ++I)
  965. RewriteMethodDeclaration(*I);
  966. for (ObjCCategoryDecl::classmeth_iterator
  967. I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
  968. I != E; ++I)
  969. RewriteMethodDeclaration(*I);
  970. // Lastly, comment out the @end.
  971. ReplaceText(CatDecl->getAtEndRange().getBegin(),
  972. strlen("@end"), "/* @end */");
  973. }
  974. void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
  975. SourceLocation LocStart = PDecl->getLocStart();
  976. assert(PDecl->isThisDeclarationADefinition());
  977. // FIXME: handle protocol headers that are declared across multiple lines.
  978. ReplaceText(LocStart, 0, "// ");
  979. for (ObjCProtocolDecl::instmeth_iterator
  980. I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
  981. I != E; ++I)
  982. RewriteMethodDeclaration(*I);
  983. for (ObjCProtocolDecl::classmeth_iterator
  984. I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
  985. I != E; ++I)
  986. RewriteMethodDeclaration(*I);
  987. for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(),
  988. E = PDecl->prop_end(); I != E; ++I)
  989. RewriteProperty(*I);
  990. // Lastly, comment out the @end.
  991. SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
  992. ReplaceText(LocEnd, strlen("@end"), "/* @end */");
  993. // Must comment out @optional/@required
  994. const char *startBuf = SM->getCharacterData(LocStart);
  995. const char *endBuf = SM->getCharacterData(LocEnd);
  996. for (const char *p = startBuf; p < endBuf; p++) {
  997. if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
  998. SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
  999. ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
  1000. }
  1001. else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
  1002. SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
  1003. ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
  1004. }
  1005. }
  1006. }
  1007. void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
  1008. SourceLocation LocStart = (*D.begin())->getLocStart();
  1009. if (LocStart.isInvalid())
  1010. llvm_unreachable("Invalid SourceLocation");
  1011. // FIXME: handle forward protocol that are declared across multiple lines.
  1012. ReplaceText(LocStart, 0, "// ");
  1013. }
  1014. void
  1015. RewriteModernObjC::RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG) {
  1016. SourceLocation LocStart = DG[0]->getLocStart();
  1017. if (LocStart.isInvalid())
  1018. llvm_unreachable("Invalid SourceLocation");
  1019. // FIXME: handle forward protocol that are declared across multiple lines.
  1020. ReplaceText(LocStart, 0, "// ");
  1021. }
  1022. void
  1023. RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
  1024. SourceLocation LocStart = LSD->getExternLoc();
  1025. if (LocStart.isInvalid())
  1026. llvm_unreachable("Invalid extern SourceLocation");
  1027. ReplaceText(LocStart, 0, "// ");
  1028. if (!LSD->hasBraces())
  1029. return;
  1030. // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
  1031. SourceLocation LocRBrace = LSD->getRBraceLoc();
  1032. if (LocRBrace.isInvalid())
  1033. llvm_unreachable("Invalid rbrace SourceLocation");
  1034. ReplaceText(LocRBrace, 0, "// ");
  1035. }
  1036. void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
  1037. const FunctionType *&FPRetType) {
  1038. if (T->isObjCQualifiedIdType())
  1039. ResultStr += "id";
  1040. else if (T->isFunctionPointerType() ||
  1041. T->isBlockPointerType()) {
  1042. // needs special handling, since pointer-to-functions have special
  1043. // syntax (where a decaration models use).
  1044. QualType retType = T;
  1045. QualType PointeeTy;
  1046. if (const PointerType* PT = retType->getAs<PointerType>())
  1047. PointeeTy = PT->getPointeeType();
  1048. else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
  1049. PointeeTy = BPT->getPointeeType();
  1050. if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
  1051. ResultStr += FPRetType->getResultType().getAsString(
  1052. Context->getPrintingPolicy());
  1053. ResultStr += "(*";
  1054. }
  1055. } else
  1056. ResultStr += T.getAsString(Context->getPrintingPolicy());
  1057. }
  1058. void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
  1059. ObjCMethodDecl *OMD,
  1060. std::string &ResultStr) {
  1061. //fprintf(stderr,"In RewriteObjCMethodDecl\n");
  1062. const FunctionType *FPRetType = 0;
  1063. ResultStr += "\nstatic ";
  1064. RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
  1065. ResultStr += " ";
  1066. // Unique method name
  1067. std::string NameStr;
  1068. if (OMD->isInstanceMethod())
  1069. NameStr += "_I_";
  1070. else
  1071. NameStr += "_C_";
  1072. NameStr += IDecl->getNameAsString();
  1073. NameStr += "_";
  1074. if (ObjCCategoryImplDecl *CID =
  1075. dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
  1076. NameStr += CID->getNameAsString();
  1077. NameStr += "_";
  1078. }
  1079. // Append selector names, replacing ':' with '_'
  1080. {
  1081. std::string selString = OMD->getSelector().getAsString();
  1082. int len = selString.size();
  1083. for (int i = 0; i < len; i++)
  1084. if (selString[i] == ':')
  1085. selString[i] = '_';
  1086. NameStr += selString;
  1087. }
  1088. // Remember this name for metadata emission
  1089. MethodInternalNames[OMD] = NameStr;
  1090. ResultStr += NameStr;
  1091. // Rewrite arguments
  1092. ResultStr += "(";
  1093. // invisible arguments
  1094. if (OMD->isInstanceMethod()) {
  1095. QualType selfTy = Context->getObjCInterfaceType(IDecl);
  1096. selfTy = Context->getPointerType(selfTy);
  1097. if (!LangOpts.MicrosoftExt) {
  1098. if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
  1099. ResultStr += "struct ";
  1100. }
  1101. // When rewriting for Microsoft, explicitly omit the structure name.
  1102. ResultStr += IDecl->getNameAsString();
  1103. ResultStr += " *";
  1104. }
  1105. else
  1106. ResultStr += Context->getObjCClassType().getAsString(
  1107. Context->getPrintingPolicy());
  1108. ResultStr += " self, ";
  1109. ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
  1110. ResultStr += " _cmd";
  1111. // Method arguments.
  1112. for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
  1113. E = OMD->param_end(); PI != E; ++PI) {
  1114. ParmVarDecl *PDecl = *PI;
  1115. ResultStr += ", ";
  1116. if (PDecl->getType()->isObjCQualifiedIdType()) {
  1117. ResultStr += "id ";
  1118. ResultStr += PDecl->getNameAsString();
  1119. } else {
  1120. std::string Name = PDecl->getNameAsString();
  1121. QualType QT = PDecl->getType();
  1122. // Make sure we convert "t (^)(...)" to "t (*)(...)".
  1123. (void)convertBlockPointerToFunctionPointer(QT);
  1124. QT.getAsStringInternal(Name, Context->getPrintingPolicy());
  1125. ResultStr += Name;
  1126. }
  1127. }
  1128. if (OMD->isVariadic())
  1129. ResultStr += "…

Large files files are truncated, but you can click here to view the full file