SourceMgr.h revision acbaecd4c8e4d19207e63624dcd9e01947b51757
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 SUPPORT_SOURCEMGR_H
17#define SUPPORT_SOURCEMGR_H
18
19#include "llvm/Support/SMLoc.h"
20
21#include <string>
22#include <vector>
23#include <cassert>
24
25namespace llvm {
26  class MemoryBuffer;
27  class SourceMgr;
28  class SMDiagnostic;
29  class Twine;
30  class raw_ostream;
31
32/// SourceMgr - This owns the files read by a parser, handles include stacks,
33/// and handles diagnostic wrangling.
34class SourceMgr {
35public:
36  /// DiagHandlerTy - Clients that want to handle their own diagnostics in a
37  /// custom way can register a function pointer+context as a diagnostic
38  /// handler.  It gets called each time PrintMessage is invoked.
39  typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context);
40private:
41  struct SrcBuffer {
42    /// Buffer - The memory buffer for the file.
43    MemoryBuffer *Buffer;
44
45    /// IncludeLoc - This is the location of the parent include, or null if at
46    /// the top level.
47    SMLoc IncludeLoc;
48  };
49
50  /// Buffers - This is all of the buffers that we are reading from.
51  std::vector<SrcBuffer> Buffers;
52
53  // IncludeDirectories - This is the list of directories we should search for
54  // include files in.
55  std::vector<std::string> IncludeDirectories;
56
57  /// LineNoCache - This is a cache for line number queries, its implementation
58  /// is really private to SourceMgr.cpp.
59  mutable void *LineNoCache;
60
61  DiagHandlerTy DiagHandler;
62  void *DiagContext;
63
64  SourceMgr(const SourceMgr&);    // DO NOT IMPLEMENT
65  void operator=(const SourceMgr&); // DO NOT IMPLEMENT
66public:
67  SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {}
68  ~SourceMgr();
69
70  void setIncludeDirs(const std::vector<std::string> &Dirs) {
71    IncludeDirectories = Dirs;
72  }
73
74  /// setDiagHandler - Specify a diagnostic handler to be invoked every time
75  /// PrintMessage is called. Ctx is passed into the handler when it is invoked.
76  void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0) {
77    DiagHandler = DH;
78    DiagContext = Ctx;
79  }
80
81  const SrcBuffer &getBufferInfo(unsigned i) const {
82    assert(i < Buffers.size() && "Invalid Buffer ID!");
83    return Buffers[i];
84  }
85
86  const MemoryBuffer *getMemoryBuffer(unsigned i) const {
87    assert(i < Buffers.size() && "Invalid Buffer ID!");
88    return Buffers[i].Buffer;
89  }
90
91  SMLoc getParentIncludeLoc(unsigned i) const {
92    assert(i < Buffers.size() && "Invalid Buffer ID!");
93    return Buffers[i].IncludeLoc;
94  }
95
96  /// AddNewSourceBuffer - Add a new source buffer to this source manager.  This
97  /// takes ownership of the memory buffer.
98  unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
99    SrcBuffer NB;
100    NB.Buffer = F;
101    NB.IncludeLoc = IncludeLoc;
102    Buffers.push_back(NB);
103    return Buffers.size()-1;
104  }
105
106  /// AddIncludeFile - Search for a file with the specified name in the current
107  /// directory or in one of the IncludeDirs.  If no file is found, this returns
108  /// ~0, otherwise it returns the buffer ID of the stacked file.
109  /// The full path to the included file can be found in IncludedFile.
110  unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
111                          std::string &IncludedFile);
112
113  /// FindBufferContainingLoc - Return the ID of the buffer containing the
114  /// specified location, returning -1 if not found.
115  int FindBufferContainingLoc(SMLoc Loc) const;
116
117  /// FindLineNumber - Find the line number for the specified location in the
118  /// specified file.  This is not a fast method.
119  unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
120
121  /// PrintMessage - Emit a message about the specified location with the
122  /// specified string.
123  ///
124  /// @param Type - If non-null, the kind of message (e.g., "error") which is
125  /// prefixed to the message.
126  /// @param ShowLine - Should the diagnostic show the source line.
127  void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
128                    bool ShowLine = true) const;
129
130
131  /// GetMessage - Return an SMDiagnostic at the specified location with the
132  /// specified string.
133  ///
134  /// @param Type - If non-null, the kind of message (e.g., "error") which is
135  /// prefixed to the message.
136  /// @param ShowLine - Should the diagnostic show the source line.
137  SMDiagnostic GetMessage(SMLoc Loc,
138                          const Twine &Msg, const char *Type,
139                          bool ShowLine = true) const;
140
141  /// PrintIncludeStack - Prints the names of included files and the line of the
142  /// file they were included from.  A diagnostic handler can use this before
143  /// printing its custom formatted message.
144  ///
145  /// @param IncludeLoc - The line of the include.
146  /// @param OS the raw_ostream to print on.
147  void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
148};
149
150
151/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
152/// allowing printing to a raw_ostream as a caret diagnostic.
153class SMDiagnostic {
154  const SourceMgr *SM;
155  SMLoc Loc;
156  std::string Filename;
157  int LineNo, ColumnNo;
158  std::string Message, LineContents;
159  unsigned ShowLine : 1;
160
161public:
162  // Null diagnostic.
163  SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {}
164  // Diagnostic with no location (e.g. file not found, command line arg error).
165  SMDiagnostic(const std::string &filename, const std::string &Msg)
166    : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1),
167      Message(Msg), ShowLine(false) {}
168
169  // Diagnostic with a location.
170  SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
171               int Line, int Col,
172               const std::string &Msg, const std::string &LineStr,
173               bool showline = true)
174    : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
175      LineContents(LineStr), ShowLine(showline) {}
176
177  const SourceMgr *getSourceMgr() const { return SM; }
178  SMLoc getLoc() const { return Loc; }
179  const std::string &getFilename() const { return Filename; }
180  int getLineNo() const { return LineNo; }
181  int getColumnNo() const { return ColumnNo; }
182  const std::string &getMessage() const { return Message; }
183  const std::string &getLineContents() const { return LineContents; }
184  bool getShowLine() const { return ShowLine; }
185
186  void Print(const char *ProgName, raw_ostream &S) const;
187};
188
189}  // end llvm namespace
190
191#endif
192