Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:53

0001 //===- EditedSource.h - Collection of source edits --------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H
0010 #define LLVM_CLANG_EDIT_EDITEDSOURCE_H
0011 
0012 #include "clang/Basic/IdentifierTable.h"
0013 #include "clang/Basic/LLVM.h"
0014 #include "clang/Basic/SourceLocation.h"
0015 #include "clang/Edit/FileOffset.h"
0016 #include "llvm/ADT/DenseMap.h"
0017 #include "llvm/ADT/SmallVector.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/Support/Allocator.h"
0020 #include <map>
0021 #include <tuple>
0022 #include <utility>
0023 
0024 namespace clang {
0025 
0026 class LangOptions;
0027 class PPConditionalDirectiveRecord;
0028 class SourceManager;
0029 
0030 namespace edit {
0031 
0032 class Commit;
0033 class EditsReceiver;
0034 
0035 class EditedSource {
0036   const SourceManager &SourceMgr;
0037   const LangOptions &LangOpts;
0038   const PPConditionalDirectiveRecord *PPRec;
0039 
0040   struct FileEdit {
0041     StringRef Text;
0042     unsigned RemoveLen = 0;
0043 
0044     FileEdit() = default;
0045   };
0046 
0047   using FileEditsTy = std::map<FileOffset, FileEdit>;
0048 
0049   FileEditsTy FileEdits;
0050 
0051   struct MacroArgUse {
0052     IdentifierInfo *Identifier;
0053     SourceLocation ImmediateExpansionLoc;
0054 
0055     // Location of argument use inside the top-level macro
0056     SourceLocation UseLoc;
0057 
0058     bool operator==(const MacroArgUse &Other) const {
0059       return std::tie(Identifier, ImmediateExpansionLoc, UseLoc) ==
0060              std::tie(Other.Identifier, Other.ImmediateExpansionLoc,
0061                       Other.UseLoc);
0062     }
0063   };
0064 
0065   llvm::DenseMap<SourceLocation, SmallVector<MacroArgUse, 2>> ExpansionToArgMap;
0066   SmallVector<std::pair<SourceLocation, MacroArgUse>, 2>
0067     CurrCommitMacroArgExps;
0068 
0069   IdentifierTable IdentTable;
0070   llvm::BumpPtrAllocator StrAlloc;
0071 
0072 public:
0073   EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
0074                const PPConditionalDirectiveRecord *PPRec = nullptr)
0075       : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts) {}
0076 
0077   const SourceManager &getSourceManager() const { return SourceMgr; }
0078   const LangOptions &getLangOpts() const { return LangOpts; }
0079 
0080   const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
0081     return PPRec;
0082   }
0083 
0084   bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
0085 
0086   bool commit(const Commit &commit);
0087 
0088   void applyRewrites(EditsReceiver &receiver, bool adjustRemovals = true);
0089   void clearRewrites();
0090 
0091   StringRef copyString(StringRef str) { return str.copy(StrAlloc); }
0092   StringRef copyString(const Twine &twine);
0093 
0094 private:
0095   bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text,
0096                     bool beforePreviousInsertions);
0097   bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
0098                              FileOffset InsertFromRangeOffs, unsigned Len,
0099                              bool beforePreviousInsertions);
0100   void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len);
0101 
0102   StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
0103                           bool &Invalid);
0104   FileEditsTy::iterator getActionForOffset(FileOffset Offs);
0105   void deconstructMacroArgLoc(SourceLocation Loc,
0106                               SourceLocation &ExpansionLoc,
0107                               MacroArgUse &ArgUse);
0108 
0109   void startingCommit();
0110   void finishedCommit();
0111 };
0112 
0113 } // namespace edit
0114 
0115 } // namespace clang
0116 
0117 #endif // LLVM_CLANG_EDIT_EDITEDSOURCE_H