1*0b57cec5SDimitry Andric //===-- Internals.h - Implementation Details---------------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H 10*0b57cec5SDimitry Andric #define LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "clang/ARCMigrate/ARCMT.h" 13*0b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 16*0b57cec5SDimitry Andric #include <list> 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric namespace clang { 19*0b57cec5SDimitry Andric class Sema; 20*0b57cec5SDimitry Andric class Stmt; 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric namespace arcmt { 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric class CapturedDiagList { 25*0b57cec5SDimitry Andric typedef std::list<StoredDiagnostic> ListTy; 26*0b57cec5SDimitry Andric ListTy List; 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric public: 29*0b57cec5SDimitry Andric void push_back(const StoredDiagnostic &diag) { List.push_back(diag); } 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric bool clearDiagnostic(ArrayRef<unsigned> IDs, SourceRange range); 32*0b57cec5SDimitry Andric bool hasDiagnostic(ArrayRef<unsigned> IDs, SourceRange range) const; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric void reportDiagnostics(DiagnosticsEngine &diags) const; 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric bool hasErrors() const; 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric typedef ListTy::const_iterator iterator; 39*0b57cec5SDimitry Andric iterator begin() const { return List.begin(); } 40*0b57cec5SDimitry Andric iterator end() const { return List.end(); } 41*0b57cec5SDimitry Andric }; 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric void writeARCDiagsToPlist(const std::string &outPath, 44*0b57cec5SDimitry Andric ArrayRef<StoredDiagnostic> diags, 45*0b57cec5SDimitry Andric SourceManager &SM, const LangOptions &LangOpts); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric class TransformActions { 48*0b57cec5SDimitry Andric DiagnosticsEngine &Diags; 49*0b57cec5SDimitry Andric CapturedDiagList &CapturedDiags; 50*0b57cec5SDimitry Andric void *Impl; // TransformActionsImpl. 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric public: 53*0b57cec5SDimitry Andric TransformActions(DiagnosticsEngine &diag, CapturedDiagList &capturedDiags, 54*0b57cec5SDimitry Andric ASTContext &ctx, Preprocessor &PP); 55*0b57cec5SDimitry Andric ~TransformActions(); 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric void startTransaction(); 58*0b57cec5SDimitry Andric bool commitTransaction(); 59*0b57cec5SDimitry Andric void abortTransaction(); 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric void insert(SourceLocation loc, StringRef text); 62*0b57cec5SDimitry Andric void insertAfterToken(SourceLocation loc, StringRef text); 63*0b57cec5SDimitry Andric void remove(SourceRange range); 64*0b57cec5SDimitry Andric void removeStmt(Stmt *S); 65*0b57cec5SDimitry Andric void replace(SourceRange range, StringRef text); 66*0b57cec5SDimitry Andric void replace(SourceRange range, SourceRange replacementRange); 67*0b57cec5SDimitry Andric void replaceStmt(Stmt *S, StringRef text); 68*0b57cec5SDimitry Andric void replaceText(SourceLocation loc, StringRef text, 69*0b57cec5SDimitry Andric StringRef replacementText); 70*0b57cec5SDimitry Andric void increaseIndentation(SourceRange range, 71*0b57cec5SDimitry Andric SourceLocation parentIndent); 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric bool clearDiagnostic(ArrayRef<unsigned> IDs, SourceRange range); 74*0b57cec5SDimitry Andric bool clearAllDiagnostics(SourceRange range) { 75*0b57cec5SDimitry Andric return clearDiagnostic(None, range); 76*0b57cec5SDimitry Andric } 77*0b57cec5SDimitry Andric bool clearDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { 78*0b57cec5SDimitry Andric unsigned IDs[] = { ID1, ID2 }; 79*0b57cec5SDimitry Andric return clearDiagnostic(IDs, range); 80*0b57cec5SDimitry Andric } 81*0b57cec5SDimitry Andric bool clearDiagnostic(unsigned ID1, unsigned ID2, unsigned ID3, 82*0b57cec5SDimitry Andric SourceRange range) { 83*0b57cec5SDimitry Andric unsigned IDs[] = { ID1, ID2, ID3 }; 84*0b57cec5SDimitry Andric return clearDiagnostic(IDs, range); 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric bool hasDiagnostic(unsigned ID, SourceRange range) { 88*0b57cec5SDimitry Andric return CapturedDiags.hasDiagnostic(ID, range); 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric bool hasDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { 92*0b57cec5SDimitry Andric unsigned IDs[] = { ID1, ID2 }; 93*0b57cec5SDimitry Andric return CapturedDiags.hasDiagnostic(IDs, range); 94*0b57cec5SDimitry Andric } 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric DiagnosticBuilder report(SourceLocation loc, unsigned diagId, 97*0b57cec5SDimitry Andric SourceRange range = SourceRange()); 98*0b57cec5SDimitry Andric void reportError(StringRef error, SourceLocation loc, 99*0b57cec5SDimitry Andric SourceRange range = SourceRange()); 100*0b57cec5SDimitry Andric void reportWarning(StringRef warning, SourceLocation loc, 101*0b57cec5SDimitry Andric SourceRange range = SourceRange()); 102*0b57cec5SDimitry Andric void reportNote(StringRef note, SourceLocation loc, 103*0b57cec5SDimitry Andric SourceRange range = SourceRange()); 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric bool hasReportedErrors() const { 106*0b57cec5SDimitry Andric return Diags.hasUnrecoverableErrorOccurred(); 107*0b57cec5SDimitry Andric } 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric class RewriteReceiver { 110*0b57cec5SDimitry Andric public: 111*0b57cec5SDimitry Andric virtual ~RewriteReceiver(); 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric virtual void insert(SourceLocation loc, StringRef text) = 0; 114*0b57cec5SDimitry Andric virtual void remove(CharSourceRange range) = 0; 115*0b57cec5SDimitry Andric virtual void increaseIndentation(CharSourceRange range, 116*0b57cec5SDimitry Andric SourceLocation parentIndent) = 0; 117*0b57cec5SDimitry Andric }; 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric void applyRewrites(RewriteReceiver &receiver); 120*0b57cec5SDimitry Andric }; 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric class Transaction { 123*0b57cec5SDimitry Andric TransformActions &TA; 124*0b57cec5SDimitry Andric bool Aborted; 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric public: 127*0b57cec5SDimitry Andric Transaction(TransformActions &TA) : TA(TA), Aborted(false) { 128*0b57cec5SDimitry Andric TA.startTransaction(); 129*0b57cec5SDimitry Andric } 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric ~Transaction() { 132*0b57cec5SDimitry Andric if (!isAborted()) 133*0b57cec5SDimitry Andric TA.commitTransaction(); 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric void abort() { 137*0b57cec5SDimitry Andric TA.abortTransaction(); 138*0b57cec5SDimitry Andric Aborted = true; 139*0b57cec5SDimitry Andric } 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric bool isAborted() const { return Aborted; } 142*0b57cec5SDimitry Andric }; 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric class MigrationPass { 145*0b57cec5SDimitry Andric public: 146*0b57cec5SDimitry Andric ASTContext &Ctx; 147*0b57cec5SDimitry Andric LangOptions::GCMode OrigGCMode; 148*0b57cec5SDimitry Andric MigratorOptions MigOptions; 149*0b57cec5SDimitry Andric Sema &SemaRef; 150*0b57cec5SDimitry Andric TransformActions &TA; 151*0b57cec5SDimitry Andric const CapturedDiagList &CapturedDiags; 152*0b57cec5SDimitry Andric std::vector<SourceLocation> &ARCMTMacroLocs; 153*0b57cec5SDimitry Andric Optional<bool> EnableCFBridgeFns; 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, 156*0b57cec5SDimitry Andric Sema &sema, TransformActions &TA, 157*0b57cec5SDimitry Andric const CapturedDiagList &capturedDiags, 158*0b57cec5SDimitry Andric std::vector<SourceLocation> &ARCMTMacroLocs) 159*0b57cec5SDimitry Andric : Ctx(Ctx), OrigGCMode(OrigGCMode), MigOptions(), 160*0b57cec5SDimitry Andric SemaRef(sema), TA(TA), CapturedDiags(capturedDiags), 161*0b57cec5SDimitry Andric ARCMTMacroLocs(ARCMTMacroLocs) { } 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric const CapturedDiagList &getDiags() const { return CapturedDiags; } 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; } 166*0b57cec5SDimitry Andric bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; } 167*0b57cec5SDimitry Andric void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; } 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric bool CFBridgingFunctionsDefined(); 170*0b57cec5SDimitry Andric }; 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric static inline StringRef getARCMTMacroName() { 173*0b57cec5SDimitry Andric return "__IMPL_ARCMT_REMOVED_EXPR__"; 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric } // end namespace arcmt 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric } // end namespace clang 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric #endif 181