xref: /freebsd/contrib/llvm-project/clang/lib/ARCMigrate/Internals.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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