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 "llvm/ADT/Optional.h"
17#include <list>
18
19namespace clang {
20  class ASTContext;
21  class Sema;
22  class Stmt;
23
24namespace arcmt {
25
26class CapturedDiagList {
27  typedef std::list<StoredDiagnostic> ListTy;
28  ListTy List;
29
30public:
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;
41  iterator begin() const { return List.begin(); }
42  iterator end()   const { return List.end();   }
43};
44
45void writeARCDiagsToPlist(const std::string &outPath,
46                          ArrayRef<StoredDiagnostic> diags,
47                          SourceManager &SM, const LangOptions &LangOpts);
48
49class TransformActions {
50  DiagnosticsEngine &Diags;
51  CapturedDiagList &CapturedDiags;
52  void *Impl; // TransformActionsImpl.
53
54public:
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);
76  bool clearAllDiagnostics(SourceRange range) {
77    return clearDiagnostic(None, range);
78  }
79  bool clearDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) {
80    unsigned IDs[] = { ID1, ID2 };
81    return clearDiagnostic(IDs, range);
82  }
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
89  bool hasDiagnostic(unsigned ID, SourceRange range) {
90    return CapturedDiags.hasDiagnostic(ID, range);
91  }
92
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
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
124class Transaction {
125  TransformActions &TA;
126  bool Aborted;
127
128public:
129  Transaction(TransformActions &TA) : TA(TA), Aborted(false) {
130    TA.startTransaction();
131  }
132
133  ~Transaction() {
134    if (!isAborted())
135      TA.commitTransaction();
136  }
137
138  void abort() {
139    TA.abortTransaction();
140    Aborted = true;
141  }
142
143  bool isAborted() const { return Aborted; }
144};
145
146class MigrationPass {
147public:
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  Optional<bool> EnableCFBridgeFns;
156
157  MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode,
158                Sema &sema, TransformActions &TA,
159                const CapturedDiagList &capturedDiags,
160                std::vector<SourceLocation> &ARCMTMacroLocs)
161    : Ctx(Ctx), OrigGCMode(OrigGCMode), MigOptions(),
162      SemaRef(sema), TA(TA), CapturedDiags(capturedDiags),
163      ARCMTMacroLocs(ARCMTMacroLocs) { }
164
165  const CapturedDiagList &getDiags() const { return CapturedDiags; }
166
167  bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; }
168  bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; }
169  void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; }
170
171  bool CFBridgingFunctionsDefined();
172};
173
174static inline StringRef getARCMTMacroName() {
175  return "__IMPL_ARCMT_REMOVED_EXPR__";
176}
177
178} // end namespace arcmt
179
180} // end namespace clang
181
182#endif
183