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