Home | History | Annotate | Download | only in Edit
      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