LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SourceMgr.h
Go to the documentation of this file.
1 //===- SourceMgr.h - Manager for Source Buffers & Diagnostics ---*- 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 // This file declares the SMDiagnostic and SourceMgr classes. This
11 // provides a simple substrate for diagnostics, #include handling, and other low
12 // level things for simple parsers.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_SUPPORT_SOURCEMGR_H
17 #define LLVM_SUPPORT_SOURCEMGR_H
18 
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/Support/SMLoc.h"
23 #include <string>
24 
25 namespace llvm {
26  class MemoryBuffer;
27  class SourceMgr;
28  class SMDiagnostic;
29  class SMFixIt;
30  class Twine;
31  class raw_ostream;
32 
33 /// SourceMgr - This owns the files read by a parser, handles include stacks,
34 /// and handles diagnostic wrangling.
35 class SourceMgr {
36 public:
37  enum DiagKind {
41  };
42 
43  /// DiagHandlerTy - Clients that want to handle their own diagnostics in a
44  /// custom way can register a function pointer+context as a diagnostic
45  /// handler. It gets called each time PrintMessage is invoked.
46  typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
47 private:
48  struct SrcBuffer {
49  /// Buffer - The memory buffer for the file.
50  MemoryBuffer *Buffer;
51 
52  /// IncludeLoc - This is the location of the parent include, or null if at
53  /// the top level.
54  SMLoc IncludeLoc;
55  };
56 
57  /// Buffers - This is all of the buffers that we are reading from.
58  std::vector<SrcBuffer> Buffers;
59 
60  // IncludeDirectories - This is the list of directories we should search for
61  // include files in.
62  std::vector<std::string> IncludeDirectories;
63 
64  /// LineNoCache - This is a cache for line number queries, its implementation
65  /// is really private to SourceMgr.cpp.
66  mutable void *LineNoCache;
67 
68  DiagHandlerTy DiagHandler;
69  void *DiagContext;
70 
72  void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
73 public:
74  SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {}
75  ~SourceMgr();
76 
77  void setIncludeDirs(const std::vector<std::string> &Dirs) {
78  IncludeDirectories = Dirs;
79  }
80 
81  /// setDiagHandler - Specify a diagnostic handler to be invoked every time
82  /// PrintMessage is called. Ctx is passed into the handler when it is invoked.
83  void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0) {
84  DiagHandler = DH;
85  DiagContext = Ctx;
86  }
87 
88  DiagHandlerTy getDiagHandler() const { return DiagHandler; }
89  void *getDiagContext() const { return DiagContext; }
90 
91  const SrcBuffer &getBufferInfo(unsigned i) const {
92  assert(i < Buffers.size() && "Invalid Buffer ID!");
93  return Buffers[i];
94  }
95 
96  const MemoryBuffer *getMemoryBuffer(unsigned i) const {
97  assert(i < Buffers.size() && "Invalid Buffer ID!");
98  return Buffers[i].Buffer;
99  }
100 
101  size_t getNumBuffers() const {
102  return Buffers.size();
103  }
104 
105  SMLoc getParentIncludeLoc(unsigned i) const {
106  assert(i < Buffers.size() && "Invalid Buffer ID!");
107  return Buffers[i].IncludeLoc;
108  }
109 
110  /// AddNewSourceBuffer - Add a new source buffer to this source manager. This
111  /// takes ownership of the memory buffer.
112  size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
113  SrcBuffer NB;
114  NB.Buffer = F;
115  NB.IncludeLoc = IncludeLoc;
116  Buffers.push_back(NB);
117  return Buffers.size() - 1;
118  }
119 
120  /// AddIncludeFile - Search for a file with the specified name in the current
121  /// directory or in one of the IncludeDirs. If no file is found, this returns
122  /// ~0, otherwise it returns the buffer ID of the stacked file.
123  /// The full path to the included file can be found in IncludedFile.
124  size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
125  std::string &IncludedFile);
126 
127  /// FindBufferContainingLoc - Return the ID of the buffer containing the
128  /// specified location, returning -1 if not found.
129  int FindBufferContainingLoc(SMLoc Loc) const;
130 
131  /// FindLineNumber - Find the line number for the specified location in the
132  /// specified file. This is not a fast method.
133  unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const {
134  return getLineAndColumn(Loc, BufferID).first;
135  }
136 
137  /// getLineAndColumn - Find the line and column number for the specified
138  /// location in the specified file. This is not a fast method.
139  std::pair<unsigned, unsigned>
140  getLineAndColumn(SMLoc Loc, int BufferID = -1) const;
141 
142  /// PrintMessage - Emit a message about the specified location with the
143  /// specified string.
144  ///
145  /// @param ShowColors - Display colored messages if output is a terminal and
146  /// the default error handler is used.
147  void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
148  const Twine &Msg,
149  ArrayRef<SMRange> Ranges = None,
150  ArrayRef<SMFixIt> FixIts = None,
151  bool ShowColors = true) const;
152 
153  /// Emits a diagnostic to llvm::errs().
154  void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
155  ArrayRef<SMRange> Ranges = None,
156  ArrayRef<SMFixIt> FixIts = None,
157  bool ShowColors = true) const;
158 
159  /// GetMessage - Return an SMDiagnostic at the specified location with the
160  /// specified string.
161  ///
162  /// @param Msg If non-null, the kind of message (e.g., "error") which is
163  /// prefixed to the message.
164  SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
165  ArrayRef<SMRange> Ranges = None,
166  ArrayRef<SMFixIt> FixIts = None) const;
167 
168  /// PrintIncludeStack - Prints the names of included files and the line of the
169  /// file they were included from. A diagnostic handler can use this before
170  /// printing its custom formatted message.
171  ///
172  /// @param IncludeLoc - The line of the include.
173  /// @param OS the raw_ostream to print on.
174  void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
175 };
176 
177 
178 /// Represents a single fixit, a replacement of one range of text with another.
179 class SMFixIt {
180  SMRange Range;
181 
182  std::string Text;
183 
184 public:
185  // FIXME: Twine.str() is not very efficient.
186  SMFixIt(SMLoc Loc, const Twine &Insertion)
187  : Range(Loc, Loc), Text(Insertion.str()) {
188  assert(Loc.isValid());
189  }
190 
191  // FIXME: Twine.str() is not very efficient.
192  SMFixIt(SMRange R, const Twine &Replacement)
193  : Range(R), Text(Replacement.str()) {
194  assert(R.isValid());
195  }
196 
197  StringRef getText() const { return Text; }
198  SMRange getRange() const { return Range; }
199 
200  bool operator<(const SMFixIt &Other) const {
201  if (Range.Start.getPointer() != Other.Range.Start.getPointer())
202  return Range.Start.getPointer() < Other.Range.Start.getPointer();
203  if (Range.End.getPointer() != Other.Range.End.getPointer())
204  return Range.End.getPointer() < Other.Range.End.getPointer();
205  return Text < Other.Text;
206  }
207 };
208 
209 
210 /// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
211 /// allowing printing to a raw_ostream as a caret diagnostic.
213  const SourceMgr *SM;
214  SMLoc Loc;
215  std::string Filename;
216  int LineNo, ColumnNo;
217  SourceMgr::DiagKind Kind;
218  std::string Message, LineContents;
219  std::vector<std::pair<unsigned, unsigned> > Ranges;
221 
222 public:
223  // Null diagnostic.
225  : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
226  // Diagnostic with no location (e.g. file not found, command line arg error).
228  : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
229  Message(Msg) {}
230 
231  // Diagnostic with a location.
232  SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
233  int Line, int Col, SourceMgr::DiagKind Kind,
234  StringRef Msg, StringRef LineStr,
235  ArrayRef<std::pair<unsigned,unsigned> > Ranges,
236  ArrayRef<SMFixIt> FixIts = None);
237 
238  const SourceMgr *getSourceMgr() const { return SM; }
239  SMLoc getLoc() const { return Loc; }
240  StringRef getFilename() const { return Filename; }
241  int getLineNo() const { return LineNo; }
242  int getColumnNo() const { return ColumnNo; }
243  SourceMgr::DiagKind getKind() const { return Kind; }
244  StringRef getMessage() const { return Message; }
245  StringRef getLineContents() const { return LineContents; }
247  return Ranges;
248  }
249 
250  void addFixIt(const SMFixIt &Hint) {
251  FixIts.push_back(Hint);
252  }
253 
255  return FixIts;
256  }
257 
258  void print(const char *ProgName, raw_ostream &S,
259  bool ShowColors = true) const;
260 };
261 
262 } // end llvm namespace
263 
264 #endif
void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const
Definition: SourceMgr.cpp:132
const char * getPointer() const
Definition: SMLoc.h:33
SMFixIt(SMLoc Loc, const Twine &Insertion)
Definition: SourceMgr.h:186
void * getDiagContext() const
Definition: SourceMgr.h:89
F(f)
void addFixIt(const SMFixIt &Hint)
Definition: SourceMgr.h:250
SMLoc Start
Definition: SMLoc.h:49
SMLoc getLoc() const
Definition: SourceMgr.h:239
StringRef getLineContents() const
Definition: SourceMgr.h:245
size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Definition: SourceMgr.cpp:55
bool isValid() const
Definition: SMLoc.h:28
StringRef getMessage() const
Definition: SourceMgr.h:244
StringRef getFilename() const
Definition: SourceMgr.h:240
SMRange getRange() const
Definition: SourceMgr.h:198
StringRef getText() const
Definition: SourceMgr.h:197
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
Definition: SourceMgr.h:46
ArrayRef< SMFixIt > getFixIts() const
Definition: SourceMgr.h:254
const SrcBuffer & getBufferInfo(unsigned i) const
Definition: SourceMgr.h:91
Represents a single fixit, a replacement of one range of text with another.
Definition: SourceMgr.h:179
ArrayRef< std::pair< unsigned, unsigned > > getRanges() const
Definition: SourceMgr.h:246
int getColumnNo() const
Definition: SourceMgr.h:242
SourceMgr::DiagKind getKind() const
Definition: SourceMgr.h:243
bool operator<(const SMFixIt &Other) const
Definition: SourceMgr.h:200
int getLineNo() const
Definition: SourceMgr.h:241
SMLoc getParentIncludeLoc(unsigned i) const
Definition: SourceMgr.h:105
#define LLVM_DELETED_FUNCTION
Definition: Compiler.h:137
unsigned FindLineNumber(SMLoc Loc, int BufferID=-1) const
Definition: SourceMgr.h:133
SMLoc End
Definition: SMLoc.h:49
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true) const
Definition: SourceMgr.cpp:348
const MemoryBuffer * getMemoryBuffer(unsigned i) const
Definition: SourceMgr.h:96
bool isValid() const
Definition: SMLoc.h:57
int FindBufferContainingLoc(SMLoc Loc) const
Definition: SourceMgr.cpp:76
std::pair< unsigned, unsigned > getLineAndColumn(SMLoc Loc, int BufferID=-1) const
Definition: SourceMgr.cpp:89
void setDiagHandler(DiagHandlerTy DH, void *Ctx=0)
Definition: SourceMgr.h:83
size_t getNumBuffers() const
Definition: SourceMgr.h:101
void setIncludeDirs(const std::vector< std::string > &Dirs)
Definition: SourceMgr.h:77
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
Definition: SourceMgr.h:227
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None) const
Definition: SourceMgr.cpp:151
const SourceMgr * getSourceMgr() const
Definition: SourceMgr.h:238
const StringRef filename(StringRef path)
Get filename.
Definition: Path.cpp:467
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Definition: SourceMgr.cpp:214
Represents a location in source code.
Definition: SMLoc.h:23
size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc)
Definition: SourceMgr.h:112
SMFixIt(SMRange R, const Twine &Replacement)
Definition: SourceMgr.h:192
DiagHandlerTy getDiagHandler() const
Definition: SourceMgr.h:88