File indexing completed on 2026-05-10 08:44:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_SUPPORT_SOURCEMGR_H
0016 #define LLVM_SUPPORT_SOURCEMGR_H
0017
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/Support/MemoryBuffer.h"
0020 #include "llvm/Support/SMLoc.h"
0021 #include <vector>
0022
0023 namespace llvm {
0024
0025 class raw_ostream;
0026 class SMDiagnostic;
0027 class SMFixIt;
0028
0029
0030
0031 class SourceMgr {
0032 public:
0033 enum DiagKind {
0034 DK_Error,
0035 DK_Warning,
0036 DK_Remark,
0037 DK_Note,
0038 };
0039
0040
0041
0042
0043 using DiagHandlerTy = void (*)(const SMDiagnostic &, void *Context);
0044
0045 private:
0046 struct SrcBuffer {
0047
0048 std::unique_ptr<MemoryBuffer> Buffer;
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 mutable void *OffsetCache = nullptr;
0061
0062
0063
0064 unsigned getLineNumber(const char *Ptr) const;
0065 template <typename T>
0066 unsigned getLineNumberSpecialized(const char *Ptr) const;
0067
0068
0069
0070 const char *getPointerForLineNumber(unsigned LineNo) const;
0071 template <typename T>
0072 const char *getPointerForLineNumberSpecialized(unsigned LineNo) const;
0073
0074
0075 SMLoc IncludeLoc;
0076
0077 SrcBuffer() = default;
0078 SrcBuffer(SrcBuffer &&);
0079 SrcBuffer(const SrcBuffer &) = delete;
0080 SrcBuffer &operator=(const SrcBuffer &) = delete;
0081 ~SrcBuffer();
0082 };
0083
0084
0085 std::vector<SrcBuffer> Buffers;
0086
0087
0088 std::vector<std::string> IncludeDirectories;
0089
0090 DiagHandlerTy DiagHandler = nullptr;
0091 void *DiagContext = nullptr;
0092
0093 bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
0094
0095 public:
0096 SourceMgr() = default;
0097 SourceMgr(const SourceMgr &) = delete;
0098 SourceMgr &operator=(const SourceMgr &) = delete;
0099 SourceMgr(SourceMgr &&) = default;
0100 SourceMgr &operator=(SourceMgr &&) = default;
0101 ~SourceMgr() = default;
0102
0103
0104 ArrayRef<std::string> getIncludeDirs() const { return IncludeDirectories; }
0105
0106 void setIncludeDirs(const std::vector<std::string> &Dirs) {
0107 IncludeDirectories = Dirs;
0108 }
0109
0110
0111
0112 void setDiagHandler(DiagHandlerTy DH, void *Ctx = nullptr) {
0113 DiagHandler = DH;
0114 DiagContext = Ctx;
0115 }
0116
0117 DiagHandlerTy getDiagHandler() const { return DiagHandler; }
0118 void *getDiagContext() const { return DiagContext; }
0119
0120 const SrcBuffer &getBufferInfo(unsigned i) const {
0121 assert(isValidBufferID(i));
0122 return Buffers[i - 1];
0123 }
0124
0125 const MemoryBuffer *getMemoryBuffer(unsigned i) const {
0126 assert(isValidBufferID(i));
0127 return Buffers[i - 1].Buffer.get();
0128 }
0129
0130 unsigned getNumBuffers() const { return Buffers.size(); }
0131
0132 unsigned getMainFileID() const {
0133 assert(getNumBuffers());
0134 return 1;
0135 }
0136
0137 SMLoc getParentIncludeLoc(unsigned i) const {
0138 assert(isValidBufferID(i));
0139 return Buffers[i - 1].IncludeLoc;
0140 }
0141
0142
0143
0144 unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
0145 SMLoc IncludeLoc) {
0146 SrcBuffer NB;
0147 NB.Buffer = std::move(F);
0148 NB.IncludeLoc = IncludeLoc;
0149 Buffers.push_back(std::move(NB));
0150 return Buffers.size();
0151 }
0152
0153
0154
0155
0156
0157 void takeSourceBuffersFrom(SourceMgr &SrcMgr,
0158 SMLoc MainBufferIncludeLoc = SMLoc()) {
0159 if (SrcMgr.Buffers.empty())
0160 return;
0161
0162 size_t OldNumBuffers = getNumBuffers();
0163 std::move(SrcMgr.Buffers.begin(), SrcMgr.Buffers.end(),
0164 std::back_inserter(Buffers));
0165 SrcMgr.Buffers.clear();
0166 Buffers[OldNumBuffers].IncludeLoc = MainBufferIncludeLoc;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175 unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
0176 std::string &IncludedFile);
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 ErrorOr<std::unique_ptr<MemoryBuffer>>
0187 OpenIncludeFile(const std::string &Filename, std::string &IncludedFile);
0188
0189
0190
0191
0192 unsigned FindBufferContainingLoc(SMLoc Loc) const;
0193
0194
0195
0196 unsigned FindLineNumber(SMLoc Loc, unsigned BufferID = 0) const {
0197 return getLineAndColumn(Loc, BufferID).first;
0198 }
0199
0200
0201
0202 std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
0203 unsigned BufferID = 0) const;
0204
0205
0206
0207 std::string getFormattedLocationNoOffset(SMLoc Loc,
0208 bool IncludePath = false) const;
0209
0210
0211
0212 SMLoc FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
0213 unsigned ColNo);
0214
0215
0216
0217
0218
0219 void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg,
0220 ArrayRef<SMRange> Ranges = {},
0221 ArrayRef<SMFixIt> FixIts = {},
0222 bool ShowColors = true) const;
0223
0224
0225 void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
0226 ArrayRef<SMRange> Ranges = {},
0227 ArrayRef<SMFixIt> FixIts = {},
0228 bool ShowColors = true) const;
0229
0230
0231
0232
0233
0234 void PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
0235 bool ShowColors = true) const;
0236
0237
0238
0239
0240
0241
0242 SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
0243 ArrayRef<SMRange> Ranges = {},
0244 ArrayRef<SMFixIt> FixIts = {}) const;
0245
0246
0247
0248
0249
0250
0251
0252 void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
0253 };
0254
0255
0256 class SMFixIt {
0257 SMRange Range;
0258
0259 std::string Text;
0260
0261 public:
0262 SMFixIt(SMRange R, const Twine &Replacement);
0263
0264 SMFixIt(SMLoc Loc, const Twine &Replacement)
0265 : SMFixIt(SMRange(Loc, Loc), Replacement) {}
0266
0267 StringRef getText() const { return Text; }
0268 SMRange getRange() const { return Range; }
0269
0270 bool operator<(const SMFixIt &Other) const {
0271 if (Range.Start.getPointer() != Other.Range.Start.getPointer())
0272 return Range.Start.getPointer() < Other.Range.Start.getPointer();
0273 if (Range.End.getPointer() != Other.Range.End.getPointer())
0274 return Range.End.getPointer() < Other.Range.End.getPointer();
0275 return Text < Other.Text;
0276 }
0277 };
0278
0279
0280
0281 class SMDiagnostic {
0282 const SourceMgr *SM = nullptr;
0283 SMLoc Loc;
0284 std::string Filename;
0285 int LineNo = 0;
0286 int ColumnNo = 0;
0287 SourceMgr::DiagKind Kind = SourceMgr::DK_Error;
0288 std::string Message, LineContents;
0289 std::vector<std::pair<unsigned, unsigned>> Ranges;
0290 SmallVector<SMFixIt, 4> FixIts;
0291
0292 public:
0293
0294 SMDiagnostic() = default;
0295
0296 SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
0297 : Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {}
0298
0299
0300 SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col,
0301 SourceMgr::DiagKind Kind, StringRef Msg, StringRef LineStr,
0302 ArrayRef<std::pair<unsigned, unsigned>> Ranges,
0303 ArrayRef<SMFixIt> FixIts = {});
0304
0305 const SourceMgr *getSourceMgr() const { return SM; }
0306 SMLoc getLoc() const { return Loc; }
0307 StringRef getFilename() const { return Filename; }
0308 int getLineNo() const { return LineNo; }
0309 int getColumnNo() const { return ColumnNo; }
0310 SourceMgr::DiagKind getKind() const { return Kind; }
0311 StringRef getMessage() const { return Message; }
0312 StringRef getLineContents() const { return LineContents; }
0313 ArrayRef<std::pair<unsigned, unsigned>> getRanges() const { return Ranges; }
0314
0315 void addFixIt(const SMFixIt &Hint) { FixIts.push_back(Hint); }
0316
0317 ArrayRef<SMFixIt> getFixIts() const { return FixIts; }
0318
0319 void print(const char *ProgName, raw_ostream &S, bool ShowColors = true,
0320 bool ShowKindLabel = true, bool ShowLocation = true) const;
0321 };
0322
0323 }
0324
0325 #endif