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/Edit/FileOffset.h" 15 #include "llvm/ADT/DenseMap.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/TinyPtrVector.h" 18 #include "llvm/Support/Allocator.h" 19 #include <map> 20 #include <tuple> 21 22 namespace clang { 23 class LangOptions; 24 class PPConditionalDirectiveRecord; 25 26 namespace edit { 27 class Commit; 28 class EditsReceiver; 29 30 class EditedSource { 31 const SourceManager &SourceMgr; 32 const LangOptions &LangOpts; 33 const PPConditionalDirectiveRecord *PPRec; 34 35 struct FileEdit { 36 StringRef Text; 37 unsigned RemoveLen; 38 39 FileEdit() : RemoveLen(0) {} 40 }; 41 42 typedef std::map<FileOffset, FileEdit> FileEditsTy; 43 FileEditsTy FileEdits; 44 45 struct MacroArgUse { 46 IdentifierInfo *Identifier; 47 SourceLocation ImmediateExpansionLoc; 48 // Location of argument use inside the top-level macro 49 SourceLocation UseLoc; 50 51 bool operator==(const MacroArgUse &Other) const { 52 return std::tie(Identifier, ImmediateExpansionLoc, UseLoc) == 53 std::tie(Other.Identifier, Other.ImmediateExpansionLoc, 54 Other.UseLoc); 55 } 56 }; 57 58 llvm::DenseMap<unsigned, SmallVector<MacroArgUse, 2>> ExpansionToArgMap; 59 SmallVector<std::pair<SourceLocation, MacroArgUse>, 2> 60 CurrCommitMacroArgExps; 61 62 IdentifierTable IdentTable; 63 llvm::BumpPtrAllocator StrAlloc; 64 65 public: 66 EditedSource(const SourceManager &SM, const LangOptions &LangOpts, 67 const PPConditionalDirectiveRecord *PPRec = nullptr) 68 : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts), 69 StrAlloc() { } 70 71 const SourceManager &getSourceManager() const { return SourceMgr; } 72 const LangOptions &getLangOpts() const { return LangOpts; } 73 const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const { 74 return PPRec; 75 } 76 77 bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs); 78 79 bool commit(const Commit &commit); 80 81 void applyRewrites(EditsReceiver &receiver, bool adjustRemovals = true); 82 void clearRewrites(); 83 84 StringRef copyString(StringRef str) { return str.copy(StrAlloc); } 85 StringRef copyString(const Twine &twine); 86 87 private: 88 bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text, 89 bool beforePreviousInsertions); 90 bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs, 91 FileOffset InsertFromRangeOffs, unsigned Len, 92 bool beforePreviousInsertions); 93 void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len); 94 95 StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs, 96 bool &Invalid); 97 FileEditsTy::iterator getActionForOffset(FileOffset Offs); 98 void deconstructMacroArgLoc(SourceLocation Loc, 99 SourceLocation &ExpansionLoc, 100 MacroArgUse &ArgUse); 101 102 void startingCommit(); 103 void finishedCommit(); 104 }; 105 106 } 107 108 } // end namespace clang 109 110 #endif 111