//===- EditedSource.h - Collection of source edits --------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H #define LLVM_CLANG_EDIT_EDITEDSOURCE_H #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Edit/FileOffset.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include #include #include namespace clang { class LangOptions; class PPConditionalDirectiveRecord; class SourceManager; namespace edit { class Commit; class EditsReceiver; class EditedSource { const SourceManager &SourceMgr; const LangOptions &LangOpts; const PPConditionalDirectiveRecord *PPRec; struct FileEdit { StringRef Text; unsigned RemoveLen = 0; FileEdit() = default; }; using FileEditsTy = std::map; FileEditsTy FileEdits; struct MacroArgUse { IdentifierInfo *Identifier; SourceLocation ImmediateExpansionLoc; // Location of argument use inside the top-level macro SourceLocation UseLoc; bool operator==(const MacroArgUse &Other) const { return std::tie(Identifier, ImmediateExpansionLoc, UseLoc) == std::tie(Other.Identifier, Other.ImmediateExpansionLoc, Other.UseLoc); } }; llvm::DenseMap> ExpansionToArgMap; SmallVector, 2> CurrCommitMacroArgExps; IdentifierTable IdentTable; llvm::BumpPtrAllocator StrAlloc; public: EditedSource(const SourceManager &SM, const LangOptions &LangOpts, const PPConditionalDirectiveRecord *PPRec = nullptr) : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts) {} const SourceManager &getSourceManager() const { return SourceMgr; } const LangOptions &getLangOpts() const { return LangOpts; } const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const { return PPRec; } bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); bool commit(const Commit &commit); void applyRewrites(EditsReceiver &receiver, bool adjustRemovals = true); void clearRewrites(); StringRef copyString(StringRef str) { return str.copy(StrAlloc); } StringRef copyString(const Twine &twine); private: bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text, bool beforePreviousInsertions); bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, FileOffset InsertFromRangeOffs, unsigned Len, bool beforePreviousInsertions); void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len); StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs, bool &Invalid); FileEditsTy::iterator getActionForOffset(FileOffset Offs); void deconstructMacroArgLoc(SourceLocation Loc, SourceLocation &ExpansionLoc, MacroArgUse &ArgUse); void startingCommit(); void finishedCommit(); }; } // namespace edit } // namespace clang #endif // LLVM_CLANG_EDIT_EDITEDSOURCE_H