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