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