1 //===- EditedSource.h - Collection of source edits --------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H 11 #define LLVM_CLANG_EDIT_EDITEDSOURCE_H 12 13 #include "clang/Basic/IdentifierTable.h" 14 #include "clang/Basic/LLVM.h" 15 #include "clang/Basic/SourceLocation.h" 16 #include "clang/Edit/FileOffset.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Support/Allocator.h" 21 #include <map> 22 #include <tuple> 23 #include <utility> 24 25 namespace clang { 26 27 class LangOptions; 28 class PPConditionalDirectiveRecord; 29 class SourceManager; 30 31 namespace edit { 32 33 class Commit; 34 class EditsReceiver; 35 36 class EditedSource { 37 const SourceManager &SourceMgr; 38 const LangOptions &LangOpts; 39 const PPConditionalDirectiveRecord *PPRec; 40 41 struct FileEdit { 42 StringRef Text; 43 unsigned RemoveLen = 0; 44 45 FileEdit() = default; 46 }; 47 48 using FileEditsTy = std::map<FileOffset, FileEdit>; 49 50 FileEditsTy FileEdits; 51 52 struct MacroArgUse { 53 IdentifierInfo *Identifier; 54 SourceLocation ImmediateExpansionLoc; 55 56 // Location of argument use inside the top-level macro 57 SourceLocation UseLoc; 58 59 bool operator==(const MacroArgUse &Other) const { 60 return std::tie(Identifier, ImmediateExpansionLoc, UseLoc) == 61 std::tie(Other.Identifier, Other.ImmediateExpansionLoc, 62 Other.UseLoc); 63 } 64 }; 65 66 llvm::DenseMap<unsigned, SmallVector<MacroArgUse, 2>> ExpansionToArgMap; 67 SmallVector<std::pair<SourceLocation, MacroArgUse>, 2> 68 CurrCommitMacroArgExps; 69 70 IdentifierTable IdentTable; 71 llvm::BumpPtrAllocator StrAlloc; 72 73 public: 74 EditedSource(const SourceManager &SM, const LangOptions &LangOpts, 75 const PPConditionalDirectiveRecord *PPRec = nullptr) SourceMgr(SM)76 : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts) {} 77 getSourceManager()78 const SourceManager &getSourceManager() const { return SourceMgr; } getLangOpts()79 const LangOptions &getLangOpts() const { return LangOpts; } 80 getPPCondDirectiveRecord()81 const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const { 82 return PPRec; 83 } 84 85 bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); 86 87 bool commit(const Commit &commit); 88 89 void applyRewrites(EditsReceiver &receiver, bool adjustRemovals = true); 90 void clearRewrites(); 91 copyString(StringRef str)92 StringRef copyString(StringRef str) { return str.copy(StrAlloc); } 93 StringRef copyString(const Twine &twine); 94 95 private: 96 bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text, 97 bool beforePreviousInsertions); 98 bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, 99 FileOffset InsertFromRangeOffs, unsigned Len, 100 bool beforePreviousInsertions); 101 void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len); 102 103 StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs, 104 bool &Invalid); 105 FileEditsTy::iterator getActionForOffset(FileOffset Offs); 106 void deconstructMacroArgLoc(SourceLocation Loc, 107 SourceLocation &ExpansionLoc, 108 MacroArgUse &ArgUse); 109 110 void startingCommit(); 111 void finishedCommit(); 112 }; 113 114 } // namespace edit 115 116 } // namespace clang 117 118 #endif // LLVM_CLANG_EDIT_EDITEDSOURCE_H 119