SourceMgr.h revision 221345
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  unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc);
110
111  /// FindBufferContainingLoc - Return the ID of the buffer containing the
112  /// specified location, returning -1 if not found.
113  int FindBufferContainingLoc(SMLoc Loc) const;
114
115  /// FindLineNumber - Find the line number for the specified location in the
116  /// specified file.  This is not a fast method.
117  unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
118
119  /// PrintMessage - Emit a message about the specified location with the
120  /// specified string.
121  ///
122  /// @param Type - If non-null, the kind of message (e.g., "error") which is
123  /// prefixed to the message.
124  /// @param ShowLine - Should the diagnostic show the source line.
125  void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
126                    bool ShowLine = true) const;
127
128
129  /// GetMessage - Return an SMDiagnostic at the specified location with the
130  /// specified string.
131  ///
132  /// @param Type - If non-null, the kind of message (e.g., "error") which is
133  /// prefixed to the message.
134  /// @param ShowLine - Should the diagnostic show the source line.
135  SMDiagnostic GetMessage(SMLoc Loc,
136                          const Twine &Msg, const char *Type,
137                          bool ShowLine = true) const;
138
139
140private:
141  void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
142};
143
144
145/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
146/// allowing printing to a raw_ostream as a caret diagnostic.
147class SMDiagnostic {
148  const SourceMgr *SM;
149  SMLoc Loc;
150  std::string Filename;
151  int LineNo, ColumnNo;
152  std::string Message, LineContents;
153  unsigned ShowLine : 1;
154
155public:
156  // Null diagnostic.
157  SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {}
158  // Diagnostic with no location (e.g. file not found, command line arg error).
159  SMDiagnostic(const std::string &filename, const std::string &Msg)
160    : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1),
161      Message(Msg), ShowLine(false) {}
162
163  // Diagnostic with a location.
164  SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
165               int Line, int Col,
166               const std::string &Msg, const std::string &LineStr,
167               bool showline = true)
168    : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
169      LineContents(LineStr), ShowLine(showline) {}
170
171  const SourceMgr *getSourceMgr() const { return SM; }
172  SMLoc getLoc() const { return Loc; }
173  const std::string &getFilename() const { return Filename; }
174  int getLineNo() const { return LineNo; }
175  int getColumnNo() const { return ColumnNo; }
176  const std::string &getMessage() const { return Message; }
177  const std::string &getLineContents() const { return LineContents; }
178  bool getShowLine() const { return ShowLine; }
179
180  void Print(const char *ProgName, raw_ostream &S) const;
181};
182
183}  // end llvm namespace
184
185#endif
186