10b57cec5SDimitry Andric //===-- Internals.h - Implementation Details---------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H 100b57cec5SDimitry Andric #define LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H 110b57cec5SDimitry Andric 125ffd83dbSDimitry Andric #include "clang/Basic/LangOptions.h" 130b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h" 145ffd83dbSDimitry Andric #include "clang/Frontend/MigratorOptions.h" 150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 160b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 170b57cec5SDimitry Andric #include <list> 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace clang { 205ffd83dbSDimitry Andric class ASTContext; 210b57cec5SDimitry Andric class Sema; 220b57cec5SDimitry Andric class Stmt; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace arcmt { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class CapturedDiagList { 270b57cec5SDimitry Andric typedef std::list<StoredDiagnostic> ListTy; 280b57cec5SDimitry Andric ListTy List; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric public: 310b57cec5SDimitry Andric void push_back(const StoredDiagnostic &diag) { List.push_back(diag); } 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric bool clearDiagnostic(ArrayRef<unsigned> IDs, SourceRange range); 340b57cec5SDimitry Andric bool hasDiagnostic(ArrayRef<unsigned> IDs, SourceRange range) const; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric void reportDiagnostics(DiagnosticsEngine &diags) const; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric bool hasErrors() const; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric typedef ListTy::const_iterator iterator; 410b57cec5SDimitry Andric iterator begin() const { return List.begin(); } 420b57cec5SDimitry Andric iterator end() const { return List.end(); } 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void writeARCDiagsToPlist(const std::string &outPath, 460b57cec5SDimitry Andric ArrayRef<StoredDiagnostic> diags, 470b57cec5SDimitry Andric SourceManager &SM, const LangOptions &LangOpts); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric class TransformActions { 500b57cec5SDimitry Andric DiagnosticsEngine &Diags; 510b57cec5SDimitry Andric CapturedDiagList &CapturedDiags; 520b57cec5SDimitry Andric void *Impl; // TransformActionsImpl. 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric public: 550b57cec5SDimitry Andric TransformActions(DiagnosticsEngine &diag, CapturedDiagList &capturedDiags, 560b57cec5SDimitry Andric ASTContext &ctx, Preprocessor &PP); 570b57cec5SDimitry Andric ~TransformActions(); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric void startTransaction(); 600b57cec5SDimitry Andric bool commitTransaction(); 610b57cec5SDimitry Andric void abortTransaction(); 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric void insert(SourceLocation loc, StringRef text); 640b57cec5SDimitry Andric void insertAfterToken(SourceLocation loc, StringRef text); 650b57cec5SDimitry Andric void remove(SourceRange range); 660b57cec5SDimitry Andric void removeStmt(Stmt *S); 670b57cec5SDimitry Andric void replace(SourceRange range, StringRef text); 680b57cec5SDimitry Andric void replace(SourceRange range, SourceRange replacementRange); 690b57cec5SDimitry Andric void replaceStmt(Stmt *S, StringRef text); 700b57cec5SDimitry Andric void replaceText(SourceLocation loc, StringRef text, 710b57cec5SDimitry Andric StringRef replacementText); 720b57cec5SDimitry Andric void increaseIndentation(SourceRange range, 730b57cec5SDimitry Andric SourceLocation parentIndent); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric bool clearDiagnostic(ArrayRef<unsigned> IDs, SourceRange range); 760b57cec5SDimitry Andric bool clearAllDiagnostics(SourceRange range) { 770b57cec5SDimitry Andric return clearDiagnostic(None, range); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric bool clearDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { 800b57cec5SDimitry Andric unsigned IDs[] = { ID1, ID2 }; 810b57cec5SDimitry Andric return clearDiagnostic(IDs, range); 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric bool clearDiagnostic(unsigned ID1, unsigned ID2, unsigned ID3, 840b57cec5SDimitry Andric SourceRange range) { 850b57cec5SDimitry Andric unsigned IDs[] = { ID1, ID2, ID3 }; 860b57cec5SDimitry Andric return clearDiagnostic(IDs, range); 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric bool hasDiagnostic(unsigned ID, SourceRange range) { 900b57cec5SDimitry Andric return CapturedDiags.hasDiagnostic(ID, range); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric bool hasDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { 940b57cec5SDimitry Andric unsigned IDs[] = { ID1, ID2 }; 950b57cec5SDimitry Andric return CapturedDiags.hasDiagnostic(IDs, range); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric DiagnosticBuilder report(SourceLocation loc, unsigned diagId, 990b57cec5SDimitry Andric SourceRange range = SourceRange()); 1000b57cec5SDimitry Andric void reportError(StringRef error, SourceLocation loc, 1010b57cec5SDimitry Andric SourceRange range = SourceRange()); 1020b57cec5SDimitry Andric void reportWarning(StringRef warning, SourceLocation loc, 1030b57cec5SDimitry Andric SourceRange range = SourceRange()); 1040b57cec5SDimitry Andric void reportNote(StringRef note, SourceLocation loc, 1050b57cec5SDimitry Andric SourceRange range = SourceRange()); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric bool hasReportedErrors() const { 1080b57cec5SDimitry Andric return Diags.hasUnrecoverableErrorOccurred(); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric class RewriteReceiver { 1120b57cec5SDimitry Andric public: 1130b57cec5SDimitry Andric virtual ~RewriteReceiver(); 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric virtual void insert(SourceLocation loc, StringRef text) = 0; 1160b57cec5SDimitry Andric virtual void remove(CharSourceRange range) = 0; 1170b57cec5SDimitry Andric virtual void increaseIndentation(CharSourceRange range, 1180b57cec5SDimitry Andric SourceLocation parentIndent) = 0; 1190b57cec5SDimitry Andric }; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric void applyRewrites(RewriteReceiver &receiver); 1220b57cec5SDimitry Andric }; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric class Transaction { 1250b57cec5SDimitry Andric TransformActions &TA; 1260b57cec5SDimitry Andric bool Aborted; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric public: 1290b57cec5SDimitry Andric Transaction(TransformActions &TA) : TA(TA), Aborted(false) { 1300b57cec5SDimitry Andric TA.startTransaction(); 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric ~Transaction() { 1340b57cec5SDimitry Andric if (!isAborted()) 1350b57cec5SDimitry Andric TA.commitTransaction(); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric void abort() { 1390b57cec5SDimitry Andric TA.abortTransaction(); 1400b57cec5SDimitry Andric Aborted = true; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric bool isAborted() const { return Aborted; } 1440b57cec5SDimitry Andric }; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric class MigrationPass { 1470b57cec5SDimitry Andric public: 1480b57cec5SDimitry Andric ASTContext &Ctx; 1490b57cec5SDimitry Andric LangOptions::GCMode OrigGCMode; 1500b57cec5SDimitry Andric MigratorOptions MigOptions; 1510b57cec5SDimitry Andric Sema &SemaRef; 1520b57cec5SDimitry Andric TransformActions &TA; 1530b57cec5SDimitry Andric const CapturedDiagList &CapturedDiags; 1540b57cec5SDimitry Andric std::vector<SourceLocation> &ARCMTMacroLocs; 1550b57cec5SDimitry Andric Optional<bool> EnableCFBridgeFns; 1560b57cec5SDimitry Andric 157*04eeddc0SDimitry Andric MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, Sema &sema, 158*04eeddc0SDimitry Andric TransformActions &TA, const CapturedDiagList &capturedDiags, 1590b57cec5SDimitry Andric std::vector<SourceLocation> &ARCMTMacroLocs) 160*04eeddc0SDimitry Andric : Ctx(Ctx), OrigGCMode(OrigGCMode), SemaRef(sema), TA(TA), 161*04eeddc0SDimitry Andric CapturedDiags(capturedDiags), ARCMTMacroLocs(ARCMTMacroLocs) {} 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric const CapturedDiagList &getDiags() const { return CapturedDiags; } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; } 1660b57cec5SDimitry Andric bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; } 1670b57cec5SDimitry Andric void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric bool CFBridgingFunctionsDefined(); 1700b57cec5SDimitry Andric }; 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric static inline StringRef getARCMTMacroName() { 1730b57cec5SDimitry Andric return "__IMPL_ARCMT_REMOVED_EXPR__"; 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric } // end namespace arcmt 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric } // end namespace clang 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric #endif 181