SourceManager.h revision 5330ee071743b8a896aa46979b020e6c3ca9b1cc
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//                     The LLVM Compiler Infrastructure
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// This file is distributed under the University of Illinois Open Source
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// License. See LICENSE.TXT for details.
7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang//
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===//
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//  This file defines the SourceManager interface.
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===//
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef LLVM_CLANG_SOURCEMANAGER_H
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define LLVM_CLANG_SOURCEMANAGER_H
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "clang/Basic/LLVM.h"
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "clang/Basic/SourceLocation.h"
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/Support/Allocator.h"
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/Support/DataTypes.h"
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/PointerIntPair.h"
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/PointerUnion.h"
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/IntrusiveRefCntPtr.h"
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/ADT/DenseMap.h"
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "llvm/Support/MemoryBuffer.h"
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <map>
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <vector>
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <cassert>
29a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Projectnamespace clang {
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass Diagnostic;
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass SourceManager;
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass FileManager;
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass FileEntry;
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass LineTableInfo;
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass LangOptions;
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ASTWriter;
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ASTReader;
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// There are three different types of locations in a file: a spelling
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// location, an expansion location, and a presumed location.
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// Given an example of:
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// #define min(x, y) x < y ? x : y
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// and then later on a use of min:
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// #line 17
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// return min(a, b);
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// The expansion location is the line in the source code where the macro
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// was expanded (the return statement), the spelling location is the
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// location in the source where the macro was originally defined,
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// and the presumed location is where the line directive states that
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// the line is 17, or any other line.
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// SrcMgr - Public enums and private classes that are part of the
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// SourceManager implementation.
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace SrcMgr {
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// CharacteristicKind - This is used to represent whether a file or directory
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// holds normal user code, system code, or system code which is implicitly
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// 'extern "C"' in C++ mode.  Entire directories can be tagged with this
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// (this is maintained by DirectoryLookup and friends) as can specific
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// FileInfos when a #pragma system_header is seen or various other cases.
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  enum CharacteristicKind {
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    C_User, C_System, C_ExternCSystem
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// ContentCache - One instance of this struct is kept for every file
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// loaded or used.  This object owns the MemoryBuffer object.
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  class ContentCache {
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    enum CCFlags {
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /// \brief Whether the buffer is invalid.
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      InvalidFlag = 0x01,
77a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      /// \brief Whether the buffer should not be freed on destruction.
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      DoNotFreeFlag = 0x02
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// Buffer - The actual buffer containing the characters from the input
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// file.  This is owned by the ContentCache object.
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// The bits indicate indicates whether the buffer is invalid.
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  public:
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// Reference to the file entry representing this ContentCache.
880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// This reference does not own the FileEntry object.
890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// It is possible for this to be NULL if
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// the ContentCache encapsulates an imaginary text buffer.
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FileEntry *OrigEntry;
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief References the file which the contents were actually loaded from.
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// Can be different from 'Entry' if we overridden the contents of one file
950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// with the contents of another file.
960a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    const FileEntry *ContentsEntry;
970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// SourceLineCache - A bump pointer allocated array of offsets for each
990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// source line.  This is lazily computed.  This is owned by the
1000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// SourceManager BumpPointerAllocator object.
1010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    unsigned *SourceLineCache;
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// NumLines - The number of lines in this ContentCache.  This is only valid
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// if SourceLineCache is non-null.
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned NumLines;
1060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief Lazily computed map of macro argument chunks to their expanded
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// source location.
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    typedef std::map<unsigned, SourceLocation> MacroArgsMap;
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    MacroArgsMap *MacroArgsCache;
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// getBuffer - Returns the memory buffer for the associated content.
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \param Diag Object through which diagnostics will be emitted if the
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// buffer cannot be retrieved.
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \param Loc If specified, is the location that invalid file diagnostics
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///     will be emitted at.
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \param Invalid If non-NULL, will be set \c true if an error occurred.
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag,
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        const SourceManager &SM,
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        SourceLocation Loc = SourceLocation(),
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        bool *Invalid = 0) const;
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// getSize - Returns the size of the content encapsulated by this
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///  ContentCache. This can be the size of the source file or the size of an
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///  arbitrary scratch buffer.  If the ContentCache encapsulates a source
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///  file this size is retrieved from the file's FileEntry.
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned getSize() const;
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// getSizeBytesMapped - Returns the number of bytes actually mapped for
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// this ContentCache. This can be 0 if the MemBuffer was not actually
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// expanded.
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned getSizeBytesMapped() const;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// Returns the kind of memory used to back the memory buffer for
1380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// this content cache.  This is used for performance analysis.
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void setBuffer(const llvm::MemoryBuffer *B) {
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      assert(!Buffer.getPointer() && "MemoryBuffer already set.");
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Buffer.setPointer(B);
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Buffer.setInt(false);
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief Get the underlying buffer, returning NULL if the buffer is not
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// yet available.
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const llvm::MemoryBuffer *getRawBuffer() const {
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return Buffer.getPointer();
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief Replace the existing buffer (which will be deleted)
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// with the given buffer.
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false);
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief Determine whether the buffer itself is invalid.
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool isBufferInvalid() const {
1590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return Buffer.getInt() & InvalidFlag;
1600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief Determine whether the buffer should be freed.
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool shouldFreeBuffer() const {
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return (Buffer.getInt() & DoNotFreeFlag) == 0;
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ContentCache(const FileEntry *Ent = 0)
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        SourceLineCache(0), NumLines(0), MacroArgsCache(0) {}
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      : Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        SourceLineCache(0), NumLines(0), MacroArgsCache(0) {}
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ~ContentCache();
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// The copy ctor does not allow copies where source object has either
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///  a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///  is not transferred, so this is a logical error.
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ContentCache(const ContentCache &RHS)
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      : Buffer(0, false), SourceLineCache(0), MacroArgsCache(0)
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      OrigEntry = RHS.OrigEntry;
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ContentsEntry = RHS.ContentsEntry;
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 &&
1870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              RHS.MacroArgsCache == 0
1880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              && "Passed ContentCache object cannot own a buffer.");
1890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      NumLines = RHS.NumLines;
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  private:
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // Disable assignments.
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ContentCache &operator=(const ContentCache& RHS);
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// FileInfo - Information about a FileID, basically just the logical file
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// that it represents and include stack information.
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Each FileInfo has include stack information, indicating where it came
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// from. This information encodes the #include chain that a token was
2030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /// expanded from. The main include file has an invalid IncludeLoc.
2040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ///
2050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /// FileInfos contain a "ContentCache *", with the contents of the file.
2060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  ///
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  class FileInfo {
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// IncludeLoc - The location of the #include that brought in this file.
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// This is an invalid SLOC for the main file (top of the #include chain).
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned IncludeLoc;  // Really a SourceLocation
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \brief Number of FileIDs (files and macros) that were created during
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// preprocessing of this #include, including this SLocEntry.
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// Zero means the preprocessor didn't provide such info for this SLocEntry.
2150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    unsigned NumCreatedFIDs;
2160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// Data - This contains the ContentCache* and the bits indicating the
2180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// characteristic of the file and whether it has #line info, all bitmangled
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// together.
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    uintptr_t Data;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    friend class clang::SourceManager;
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    friend class clang::ASTWriter;
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    friend class clang::ASTReader;
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  public:
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// get - Return a FileInfo object.
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static FileInfo get(SourceLocation IL, const ContentCache *Con,
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        CharacteristicKind FileCharacter) {
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FileInfo X;
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      X.IncludeLoc = IL.getRawEncoding();
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      X.NumCreatedFIDs = 0;
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      X.Data = (uintptr_t)Con;
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
2340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      assert((unsigned)FileCharacter < 4 && "invalid file character");
2350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      X.Data |= (unsigned)FileCharacter;
2360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return X;
2370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
2380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    SourceLocation getIncludeLoc() const {
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SourceLocation::getFromRawEncoding(IncludeLoc);
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const ContentCache* getContentCache() const {
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return reinterpret_cast<const ContentCache*>(Data & ~7UL);
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// getCharacteristic - Return whether this is a system header or not.
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CharacteristicKind getFileCharacteristic() const {
2480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return (CharacteristicKind)(Data & 3);
2490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
2500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// hasLineDirectives - Return true if this FileID has #line directives in
2520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// it.
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool hasLineDirectives() const { return (Data & 4) != 0; }
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// setHasLineDirectives - Set the flag that indicates that this FileID has
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// line table entries associated with it.
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void setHasLineDirectives() {
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Data |= 4;
2590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
2600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  };
2610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /// ExpansionInfo - Each ExpansionInfo encodes the expansion location - where
2630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /// the token was ultimately expanded, and the SpellingLoc - where the actual
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// character data for the token came from.
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  class ExpansionInfo {
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // Really these are all SourceLocations.
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// SpellingLoc - Where the spelling for the token can be found.
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned SpellingLoc;
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// ExpansionLocStart/ExpansionLocEnd - In a macro expansion, these
2720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /// indicate the start and end of the expansion. In object-like macros,
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// these will be the same. In a function-like macro expansion, the start
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// will be the identifier and the end will be the ')'. Finally, in
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// macro-argument instantitions, the end will be 'SourceLocation()', an
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// invalid location.
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned ExpansionLocStart, ExpansionLocEnd;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  public:
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    SourceLocation getSpellingLoc() const {
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SourceLocation::getFromRawEncoding(SpellingLoc);
2820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
2830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    SourceLocation getExpansionLocStart() const {
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SourceLocation::getFromRawEncoding(ExpansionLocStart);
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    SourceLocation getExpansionLocEnd() const {
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      SourceLocation EndLoc =
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        SourceLocation::getFromRawEncoding(ExpansionLocEnd);
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc;
290a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    }
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const {
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return std::make_pair(getExpansionLocStart(), getExpansionLocEnd());
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool isMacroArgExpansion() const {
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      // Note that this needs to return false for default constructed objects.
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return getExpansionLocStart().isValid() &&
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid();
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// create - Return a ExpansionInfo for an expansion. Start and End specify
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// the expansion range (where the macro is expanded), and SpellingLoc
304a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    /// specifies the spelling location (where the characters from the token
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// come from). All three can refer to normal File SLocs or expansion
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// locations.
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static ExpansionInfo create(SourceLocation SpellingLoc,
308a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                                SourceLocation Start, SourceLocation End) {
309a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      ExpansionInfo X;
310a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      X.SpellingLoc = SpellingLoc.getRawEncoding();
311a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      X.ExpansionLocStart = Start.getRawEncoding();
312a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      X.ExpansionLocEnd = End.getRawEncoding();
313a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return X;
314a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    }
315295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
316aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /// createForMacroArg - Return a special ExpansionInfo for the expansion of
317aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /// a macro argument into a function-like macro's body. ExpansionLoc
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// specifies the expansion location (where the macro is expanded). This
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// doesn't need to be a range because a macro is always expanded at
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// a macro parameter reference, and macro parameters are always exactly
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// one token. SpellingLoc specifies the spelling location (where the
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// characters from the token come from). ExpansionLoc and SpellingLoc can
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// both refer to normal File SLocs or expansion locations.
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// Given the code:
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \code
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///   #define F(x) f(x)
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///   F(42);
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// \endcode
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ///
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// When expanding '\c F(42)', the '\c x' would call this with an
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// SpellingLoc pointing at '\c 42' anad an ExpansionLoc pointing at its
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /// location in the definition of '\c F'.
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc,
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           SourceLocation ExpansionLoc) {
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      // We store an intentionally invalid source location for the end of the
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      // expansion range to mark that this is a macro argument ion rather than
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      // a normal one.
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return create(SpellingLoc, ExpansionLoc, SourceLocation());
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// SLocEntry - This is a discriminated union of FileInfo and
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// ExpansionInfo.  SourceManager keeps an array of these objects, and
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// they are uniquely identified by the FileID datatype.
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  class SLocEntry {
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned Offset;   // low bit is set for expansion info.
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    union {
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FileInfo File;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ExpansionInfo Expansion;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  public:
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned getOffset() const { return Offset >> 1; }
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool isExpansion() const { return Offset & 1; }
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool isFile() const { return !isExpansion(); }
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FileInfo &getFile() const {
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      assert(isFile() && "Not a file SLocEntry!");
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return File;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const ExpansionInfo &getExpansion() const {
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      assert(isExpansion() && "Not a macro expansion SLocEntry!");
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return Expansion;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static SLocEntry get(unsigned Offset, const FileInfo &FI) {
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      SLocEntry E;
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      E.Offset = Offset << 1;
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      E.File = FI;
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return E;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) {
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      SLocEntry E;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      E.Offset = (Offset << 1) | 1;
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      E.Expansion = Expansion;
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return E;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}  // end SrcMgr namespace.
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// \brief External source of source location entries.
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ExternalSLocEntrySource {
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  virtual ~ExternalSLocEntrySource();
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Read the source location entry with index ID, which will always be
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// less than -1.
391a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \returns true if an error occurred that prevented the source-location
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// entry from being loaded.
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  virtual bool ReadSLocEntry(int ID) = 0;
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// IsBeforeInTranslationUnitCache - This class holds the cache used by
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// isBeforeInTranslationUnit.  The cache structure is complex enough to be
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// worth breaking out of SourceManager.
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass IsBeforeInTranslationUnitCache {
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// L/R QueryFID - These are the FID's of the cached query.  If these match up
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// with a subsequent query, the result can be reused.
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID LQueryFID, RQueryFID;
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief True if LQueryFID was created before RQueryFID. This is used
407a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// to compare macro expansion locations.
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool IsLQFIDBeforeRQFID;
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// CommonFID - This is the file found in common between the two #include
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// traces.  It is the nearest common ancestor of the #include tree.
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID CommonFID;
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// L/R CommonOffset - This is the offset of the previous query in CommonFID.
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Usually, this represents the location of the #include for QueryFID, but if
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// random token in the parent.
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned LCommonOffset, RCommonOffset;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// isCacheValid - Return true if the currently cached values match up with
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// the specified LHS/RHS query.  If not, we can't use the cache.
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isCacheValid(FileID LHS, FileID RHS) const {
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return LQueryFID == LHS && RQueryFID == RHS;
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getCachedResult - If the cache is valid, compute the result given the
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// specified offsets in the LHS/RHS FID's.
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool getCachedResult(unsigned LOffset, unsigned ROffset) const {
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // If one of the query files is the common file, use the offset.  Otherwise,
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // use the #include loc in the common file.
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (LQueryFID != CommonFID) LOffset = LCommonOffset;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (RQueryFID != CommonFID) ROffset = RCommonOffset;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // It is common for multiple macro expansions to be "included" from the same
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // location (expansion location), in which case use the order of the FileIDs
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // to determine which came first.
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (LOffset == ROffset && LQueryFID != CommonFID && RQueryFID != CommonFID)
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return IsLQFIDBeforeRQFID;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return LOffset < ROffset;
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Set up a new query.
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) {
446a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    assert(LHS != RHS);
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    LQueryFID = LHS;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    RQueryFID = RHS;
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    IsLQFIDBeforeRQFID = isLFIDBeforeRFID;
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void clear() {
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    LQueryFID = RQueryFID = FileID();
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    IsLQFIDBeforeRQFID = false;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    unsigned rCommonOffset) {
459a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    CommonFID = commonFID;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    LCommonOffset = lCommonOffset;
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    RCommonOffset = rCommonOffset;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// \brief This class handles loading and caching of source files into memory.
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// This object owns the MemoryBuffer objects for all of the loaded
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// files and assigns unique FileID's for each unique #include chain.
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// The SourceManager can be queried for information about SourceLocation
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// objects, turning them into either spelling or expansion locations. Spelling
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// locations represent where the bytes corresponding to a token came from and
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// expansion locations represent where the location is in the user's view. In
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// the case of a macro expansion, for example, the spelling location indicates
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// where the expanded token came from and the expansion location specifies
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// where it was expanded.
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass SourceManager : public llvm::RefCountedBase<SourceManager> {
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Diagnostic object.
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Diagnostic &Diag;
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileManager &FileMgr;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable llvm::BumpPtrAllocator ContentCacheAlloc;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// FileInfos - Memoized information about all of the files tracked by this
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// SourceManager.  This set allows us to merge ContentCache entries based
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// on their FileEntry*.  All ContentCache objects will thus have unique,
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// non-null, FileEntry pointers.
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief True if the ContentCache for files that are overriden by other
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// files, should report the original file name. Defaults to true.
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool OverridenFilesKeepOriginalName;
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Files that have been overriden with the contents from another file.
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// MemBufferInfos - Information about various memory buffers that we have
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// read in.  All FileEntry* within the stored ContentCache objects are NULL,
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// as they do not refer to a file.
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::vector<SrcMgr::ContentCache*> MemBufferInfos;
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief The table of SLocEntries that are local to this module.
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// expansion.
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::vector<SrcMgr::SLocEntry> LocalSLocEntryTable;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief The table of SLocEntries that are loaded from other modules.
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Negative FileIDs are indexes into this table. To get from ID to an index,
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// use (-ID - 2).
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::vector<SrcMgr::SLocEntry> LoadedSLocEntryTable;
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief The starting offset of the next local SLocEntry.
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// This is LocalSLocEntryTable.back().Offset + the size of that entry.
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned NextLocalOffset;
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief The starting offset of the latest batch of loaded SLocEntries.
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// This is LoadedSLocEntryTable.back().Offset, except that that entry might
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// not have been loaded, so that value would be unknown.
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned CurrentLoadedOffset;
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief The highest possible offset is 2^31-1, so CurrentLoadedOffset
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// starts at 2^31.
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const unsigned MaxLoadedOffset = 1U << 31U;
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief A bitmap that indicates whether the entries of LoadedSLocEntryTable
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// have already been loaded from the external source.
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Same indexing as LoadedSLocEntryTable.
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::vector<bool> SLocEntryLoaded;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief An external source for source location entries.
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExternalSLocEntrySource *ExternalSLocEntries;
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// LastFileIDLookup records the last FileID looked up or created, because it
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// is very common to look up many tokens from the same file.
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable FileID LastFileIDLookup;
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// LineTable - This holds information for #line directives.  It is referenced
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// by indices from SLocEntryTable.
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  LineTableInfo *LineTable;
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// LastLineNo - These ivars serve as a cache used in the getLineNumber
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// method which is used to speedup getLineNumber calls to nearby locations.
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable FileID LastLineNoFileIDQuery;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable SrcMgr::ContentCache *LastLineNoContentCache;
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable unsigned LastLineNoFilePos;
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable unsigned LastLineNoResult;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// MainFileID - The file ID for the main source file of the translation unit.
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID MainFileID;
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Statistics for -print-stats.
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable unsigned NumLinearScans, NumBinaryProbes;
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Cache results for the isBeforeInTranslationUnit method.
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Cache for the "fake" buffer used for error-recovery purposes.
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  mutable llvm::MemoryBuffer *FakeBufferForRecovery;
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // SourceManager doesn't support copy construction.
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  explicit SourceManager(const SourceManager&);
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void operator=(const SourceManager&);
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceManager(Diagnostic &Diag, FileManager &FileMgr);
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ~SourceManager();
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void clearIDTables();
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Diagnostic &getDiagnostics() const { return Diag; }
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileManager &getFileManager() const { return FileMgr; }
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Set true if the SourceManager should report the original file name
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// for contents of files that were overriden by other files.Defaults to true.
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void setOverridenFilesKeepOriginalName(bool value) {
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    OverridenFilesKeepOriginalName = value;
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// createMainFileIDForMembuffer - Create the FileID for a memory buffer
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  that will represent the FileID for the main source.  One example
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  of when this would be used is when the main source is read from STDIN.
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(MainFileID.isInvalid() && "MainFileID already set!");
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    MainFileID = createFileIDForMemBuffer(Buffer);
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return MainFileID;
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // MainFileID creation and querying methods.
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getMainFileID - Returns the FileID of the main source file.
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID getMainFileID() const { return MainFileID; }
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// createMainFileID - Create the FileID for the main source file.
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID createMainFileID(const FileEntry *SourceFile) {
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(MainFileID.isInvalid() && "MainFileID already set!");
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    MainFileID = createFileID(SourceFile, SourceLocation(), SrcMgr::C_User);
6070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return MainFileID;
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Set the file ID for the precompiled preamble, which is also the
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// main file.
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void SetPreambleFileID(FileID Preamble) {
613a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    assert(MainFileID.isInvalid() && "MainFileID already set!");
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    MainFileID = Preamble;
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
616a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Methods to create new FileID's and macro expansions.
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// createFileID - Create a new FileID that represents the specified file
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// being #included from the specified IncludePosition.  This translates NULL
623a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// into standard input.
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      SrcMgr::CharacteristicKind FileCharacter,
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      int LoadedID = 0, unsigned LoadedOffset = 0) {
627a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(IR && "getOrCreateContentCache() cannot return NULL");
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// createFileIDForMemBuffer - Create a new FileID that represents the
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// specified memory buffer.  This does no caching of the buffer and takes
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  int LoadedID = 0, unsigned LoadedOffset = 0) {
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
6380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        SrcMgr::C_User, LoadedID, LoadedOffset);
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// createMacroArgExpansionLoc - Return a new SourceLocation that encodes the
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// fact that a token from SpellingLoc should actually be referenced from
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// ExpansionLoc, and that it represents the expansion of a macro argument
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// into the function-like macro body.
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation createMacroArgExpansionLoc(SourceLocation Loc,
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            SourceLocation ExpansionLoc,
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            unsigned TokLength);
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// createExpansionLoc - Return a new SourceLocation that encodes the fact
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// that a token from SpellingLoc should actually be referenced from
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// ExpansionLoc.
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation createExpansionLoc(SourceLocation Loc,
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    SourceLocation ExpansionLocStart,
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    SourceLocation ExpansionLocEnd,
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    unsigned TokLength,
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    int LoadedID = 0,
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    unsigned LoadedOffset = 0);
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Retrieve the memory buffer associated with the given file.
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
661a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \param Invalid If non-NULL, will be set \c true if an error
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// occurs while retrieving the memory buffer.
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                   bool *Invalid = 0);
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Override the contents of the given source file by providing an
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// already-allocated buffer.
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param SourceFile the source file whose contents will be overriden.
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param Buffer the memory buffer whose contents will be used as the
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// data in the given source file.
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param DoNotFree If true, then the buffer will not be freed when the
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// source manager is destroyed.
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void overrideFileContents(const FileEntry *SourceFile,
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            const llvm::MemoryBuffer *Buffer,
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            bool DoNotFree = false);
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Override the the given source file with another one.
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param SourceFile the source file which will be overriden.
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param NewFile the file whose contents will be used as the
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// data instead of the contents of the given source file.
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void overrideFileContents(const FileEntry *SourceFile,
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            const FileEntry *NewFile);
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // FileID manipulation methods.
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getBuffer - Return the buffer for the specified FileID. If there is an
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// error opening this buffer the first time, this manufactures a temporary
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// buffer and returns a non-empty error string.
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      bool *Invalid = 0) const {
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool MyInvalid = false;
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (MyInvalid || !Entry.isFile()) {
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if (Invalid)
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *Invalid = true;
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return getFakeBufferForRecovery();
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc,
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                        Invalid);
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool MyInvalid = false;
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (MyInvalid || !Entry.isFile()) {
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if (Invalid)
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *Invalid = true;
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return getFakeBufferForRecovery();
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Entry.getFile().getContentCache()->getBuffer(Diag, *this,
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                        SourceLocation(),
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                        Invalid);
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getFileEntryForID - Returns the FileEntry record for the provided FileID.
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const FileEntry *getFileEntryForID(FileID FID) const {
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool MyInvalid = false;
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (MyInvalid || !Entry.isFile())
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Entry.getFile().getContentCache()->OrigEntry;
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Returns the FileEntry record for the provided SLocEntry.
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return sloc.getFile().getContentCache()->OrigEntry;
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getBufferData - Return a StringRef to the source buffer data for the
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// specified FileID.
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param FID The file ID whose contents will be returned.
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \param Invalid If non-NULL, will be set true if an error occurred.
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Get the number of FileIDs (files and macros) that were created
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// during preprocessing of \arg FID, including it.
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getNumCreatedFIDsForFileID(FileID FID) const {
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool Invalid = false;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Invalid || !Entry.isFile())
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Entry.getFile().NumCreatedFIDs;
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Set the number of FileIDs (files and macros) that were created
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// during preprocessing of \arg FID, including it.
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const {
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool Invalid = false;
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Invalid || !Entry.isFile())
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!");
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs;
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // SourceLocation manipulation methods.
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getFileID - Return the FileID for a SourceLocation.  This is a very
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// hot method that is used for all SourceManager queries that start with a
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// SourceLocation object.  It is responsible for finding the entry in
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// SLocEntryTable which contains the specified location.
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FileID getFileID(SourceLocation SpellingLoc) const {
782e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang    unsigned SLocOffset = SpellingLoc.getOffset();
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // If our one-entry cache covers this offset, just return it.
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return LastFileIDLookup;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getFileIDSlow(SLocOffset);
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getLocForStartOfFile - Return the source location corresponding to the
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// first byte of the specified file.
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation getLocForStartOfFile(FileID FID) const {
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool Invalid = false;
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Invalid || !Entry.isFile())
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SourceLocation();
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned FileOffset = Entry.getOffset();
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return SourceLocation::getFileLoc(FileOffset);
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Returns the include location if \arg FID is a #include'd file
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// otherwise it returns an invalid location.
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation getIncludeLoc(FileID FID) const {
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool Invalid = false;
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Invalid || !Entry.isFile())
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SourceLocation();
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Entry.getFile().getIncludeLoc();
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getExpansionLoc - Given a SourceLocation object, return the expansion
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// location referenced by the ID.
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation getExpansionLoc(SourceLocation Loc) const {
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // Handle the non-mapped case inline, defer to out of line code to handle
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // expansions.
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Loc.isFileID()) return Loc;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getExpansionLocSlowCase(Loc);
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getImmediateExpansionRange - Loc is required to be an expansion location.
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Return the start/end of the expansion information.
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::pair<SourceLocation,SourceLocation>
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  getImmediateExpansionRange(SourceLocation Loc) const;
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getExpansionRange - Given a SourceLocation object, return the range of
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// tokens covered by the expansion the ultimate file.
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::pair<SourceLocation,SourceLocation>
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  getExpansionRange(SourceLocation Loc) const;
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getSpellingLoc - Given a SourceLocation object, return the spelling
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// location referenced by the ID.  This is the place where the characters
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// that make up the lexed token can be found.
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation getSpellingLoc(SourceLocation Loc) const {
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // Handle the non-mapped case inline, defer to out of line code to handle
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    // expansions.
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Loc.isFileID()) return Loc;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getSpellingLocSlowCase(Loc);
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getImmediateSpellingLoc - Given a SourceLocation object, return the
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// spelling location referenced by the ID.  This is the first level down
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// towards the place where the characters that make up the lexed token can be
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// found.  This should not generally be used by clients.
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getDecomposedLoc - Decompose the specified location into a raw FileID +
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Offset pair.  The first element is the FileID, the second is the
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// offset from the start of the buffer of the location.
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FileID FID = getFileID(Loc);
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getDecomposedExpansionLoc - Decompose the specified location into a raw
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// FileID + Offset pair. If the location is an expansion record, walk
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// through it until we find the final location expanded.
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::pair<FileID, unsigned>
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  getDecomposedExpansionLoc(SourceLocation Loc) const {
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FileID FID = getFileID(Loc);
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned Offset = Loc.getOffset()-E->getOffset();
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Loc.isFileID())
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return std::make_pair(FID, Offset);
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getDecomposedExpansionLocSlowCase(E);
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getDecomposedSpellingLoc - Decompose the specified location into a raw
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// FileID + Offset pair.  If the location is an expansion record, walk
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// through it until we find its spelling record.
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  std::pair<FileID, unsigned>
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  getDecomposedSpellingLoc(SourceLocation Loc) const {
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FileID FID = getFileID(Loc);
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned Offset = Loc.getOffset()-E->getOffset();
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Loc.isFileID())
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return std::make_pair(FID, Offset);
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getDecomposedSpellingLocSlowCase(E, Offset);
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getFileOffset - This method returns the offset from the start
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// of the file that the specified SourceLocation represents. This is not very
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// meaningful for a macro ID.
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getFileOffset(SourceLocation SpellingLoc) const {
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getDecomposedLoc(SpellingLoc).second;
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
893a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
894a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// isMacroArgExpansion - This method tests whether the given source location
895a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// represents a macro argument's expansion into the function-like macro
896a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// definition. Such source locations only appear inside of the expansion
897a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// locations representing where a particular function-like macro was
898a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// expanded.
899a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  bool isMacroArgExpansion(SourceLocation Loc) const;
900a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
901a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \brief Returns true if \arg Loc is inside the [\arg Start, +\arg Length)
902a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// chunk of the source location address space.
903a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// If it's true and \arg RelativeOffset is non-null, it will be set to the
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// relative offset of \arg Loc inside the chunk.
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isInSLocAddrSpace(SourceLocation Loc,
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         SourceLocation Start, unsigned Length,
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         unsigned *RelativeOffset = 0) const {
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(((Start.getOffset() < NextLocalOffset &&
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               Start.getOffset()+Length <= NextLocalOffset) ||
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (Start.getOffset() >= CurrentLoadedOffset &&
911a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                Start.getOffset()+Length < MaxLoadedOffset)) &&
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           "Chunk is not valid SLoc address space");
913a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    unsigned LocOffs = Loc.getOffset();
914a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    unsigned BeginOffs = Start.getOffset();
915a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    unsigned EndOffs = BeginOffs + Length;
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (LocOffs >= BeginOffs && LocOffs < EndOffs) {
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if (RelativeOffset)
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *RelativeOffset = LocOffs - BeginOffs;
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return true;
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
922a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return false;
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Return true if both \arg LHS and \arg RHS are in the local source
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// location address space or the loaded one. If it's true and
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \arg RelativeOffset is non-null, it will be set to the offset of \arg RHS
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// relative to \arg LHS.
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS,
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             int *RelativeOffset) const {
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset();
932a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    bool LHSLoaded = LHSOffs >= CurrentLoadedOffset;
933a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    bool RHSLoaded = RHSOffs >= CurrentLoadedOffset;
934a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (LHSLoaded == RHSLoaded) {
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if (RelativeOffset)
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *RelativeOffset = RHSOffs - LHSOffs;
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return true;
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
941a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return false;
942a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  }
943a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
944a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  //===--------------------------------------------------------------------===//
945a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  // Queries about the code at a SourceLocation.
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
947a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
948a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// getCharacterData - Return a pointer to the start of the specified location
949a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// in the appropriate spelling MemoryBuffer.
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
951a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \param Invalid If non-NULL, will be set \c true if an error occurs.
952a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const;
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getColumnNumber - Return the column # for the specified file position.
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// This is significantly cheaper to compute than the line number.  This
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// returns zero if the column number isn't known.  This may only be called
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// on a file sloc, so you must choose a spelling or expansion location
958a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// before calling this method.
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getColumnNumber(FileID FID, unsigned FilePos,
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           bool *Invalid = 0) const;
961a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
962a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  unsigned getExpansionColumnNumber(SourceLocation Loc,
963a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                                    bool *Invalid = 0) const;
964a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
965a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
966a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getLineNumber - Given a SourceLocation, return the spelling line number
968a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// for the position indicated.  This requires building and caching a table of
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// line offsets for the MemoryBuffer, so this is not cheap: use only when
970a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// about to emit a diagnostic.
971a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const;
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
973a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
975a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
976a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// Return the filename or buffer identifier of the buffer the location is in.
977a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// Note that this name does not respect #line directives.  Use getPresumedLoc
978a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// for normal clients.
979a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const;
980a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
981a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// getFileCharacteristic - return the file characteristic of the specified
982a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// source location, indicating whether this is a normal file, a system
983a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// header, or an "implicit extern C" system header.
984a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///
985a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// This state can be modified with flags on GNU linemarker directives like:
986a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///   # 4 "foo.h" 3
987a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// which changes all source locations in the current file after that to be
988a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// considered to be from a system header.
989a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
990a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
991a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// getPresumedLoc - This method returns the "presumed" location of a
992a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// SourceLocation specifies.  A "presumed location" can be modified by #line
993a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// or GNU line marker directives.  This provides a view on the data that a
994a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// user should see in diagnostics, for example.
995a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///
996a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// Note that a presumed location is always given as the expansion point of
997a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// an expansion location, not at the spelling location.
998a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///
999a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \returns The presumed location of the specified SourceLocation. If the
1000a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// presumed location cannot be calculate (e.g., because \p Loc is invalid
1001a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// or the file containing \p Loc has changed on disk), returns an invalid
1002a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// presumed location.
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  PresumedLoc getPresumedLoc(SourceLocation Loc) const;
1004a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1005a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// isFromSameFile - Returns true if both SourceLocations correspond to
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  the same file.
1007a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
1008a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return getFileID(Loc1) == getFileID(Loc2);
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1010a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1011a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// isFromMainFile - Returns true if the file of provided SourceLocation is
1012a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///   the main file.
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isFromMainFile(SourceLocation Loc) const {
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getFileID(Loc) == getMainFileID();
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// isInSystemHeader - Returns if a SourceLocation is in a system header.
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isInSystemHeader(SourceLocation Loc) const {
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getFileCharacteristic(Loc) != SrcMgr::C_User;
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C"
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// system header.
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isInExternCSystemHeader(SourceLocation Loc) const {
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1027a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1028a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \brief The size of the SLocEnty that \arg FID represents.
1029a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  unsigned getFileIDSize(FileID FID) const;
1030a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1031a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \brief Given a specific FileID, returns true if \arg Loc is inside that
1032a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// FileID chunk and sets relative offset (offset of \arg Loc from beginning
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// of FileID) to \arg relativeOffset.
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isInFileID(SourceLocation Loc, FileID FID,
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  unsigned *RelativeOffset = 0) const {
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned Offs = Loc.getOffset();
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (isOffsetInFileID(FID, Offs)) {
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if (RelativeOffset)
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *RelativeOffset = Offs - getSLocEntry(FID).getOffset();
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return true;
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1043a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return false;
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1045a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1046a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  //===--------------------------------------------------------------------===//
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Line Table Manipulation Routines
1048a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  //===--------------------------------------------------------------------===//
1049a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
1051a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  ///
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getLineTableFilenameID(StringRef Str);
1053a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1054a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// AddLineNote - Add a line note to the line table for the FileID and offset
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// specified by Loc.  If FilenameID is -1, it is considered to be
1056a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// unspecified.
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
1059a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                   bool IsFileEntry, bool IsFileExit,
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   bool IsSystemHeader, bool IsExternCHeader);
1061a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Determine if the source manager has a line table.
1063a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  bool hasLineTable() const { return LineTable != 0; }
1064a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1065a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// \brief Retrieve the stored line table.
1066a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  LineTableInfo &getLineTable();
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
1069a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  // Queries for performance analysis.
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  //===--------------------------------------------------------------------===//
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1072a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// Return the total amount of physical memory allocated by the
1073a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  /// ContentCache allocator.
1074a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  size_t getContentCacheSize() const {
1075a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return ContentCacheAlloc.getTotalMemory();
1076a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  }
1077a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  struct MemoryBufferSizes {
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const size_t malloc_bytes;
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const size_t mmap_bytes;
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1082    MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
1083      : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
1084  };
1085
1086  /// Return the amount of memory used by memory buffers, breaking down
1087  /// by heap-backed versus mmap'ed memory.
1088  MemoryBufferSizes getMemoryBufferSizes() const;
1089
1090  // Return the amount of memory used for various side tables and
1091  // data structures in the SourceManager.
1092  size_t getDataStructureSizes() const;
1093
1094  //===--------------------------------------------------------------------===//
1095  // Other miscellaneous methods.
1096  //===--------------------------------------------------------------------===//
1097
1098  /// \brief Get the source location for the given file:line:col triplet.
1099  ///
1100  /// If the source file is included multiple times, the source location will
1101  /// be based upon the first inclusion.
1102  ///
1103  /// If the location points inside a function macro argument, the returned
1104  /// location will be the macro location in which the argument was expanded.
1105  /// \sa getMacroArgExpandedLocation
1106  SourceLocation getLocation(const FileEntry *SourceFile,
1107                             unsigned Line, unsigned Col) {
1108    SourceLocation Loc = translateFileLineCol(SourceFile, Line, Col);
1109    return getMacroArgExpandedLocation(Loc);
1110  }
1111
1112  /// \brief Get the source location for the given file:line:col triplet.
1113  ///
1114  /// If the source file is included multiple times, the source location will
1115  /// be based upon the first inclusion.
1116  SourceLocation translateFileLineCol(const FileEntry *SourceFile,
1117                                      unsigned Line, unsigned Col);
1118
1119  /// \brief If \arg Loc points inside a function macro argument, the returned
1120  /// location will be the macro location in which the argument was expanded.
1121  /// If a macro argument is used multiple times, the expanded location will
1122  /// be at the first expansion of the argument.
1123  /// e.g.
1124  ///   MY_MACRO(foo);
1125  ///             ^
1126  /// Passing a file location pointing at 'foo', will yield a macro location
1127  /// where 'foo' was expanded into.
1128  SourceLocation getMacroArgExpandedLocation(SourceLocation Loc);
1129
1130  /// \brief Determines the order of 2 source locations in the translation unit.
1131  ///
1132  /// \returns true if LHS source location comes before RHS, false otherwise.
1133  bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
1134
1135  /// \brief Comparison function class.
1136  class LocBeforeThanCompare : public std::binary_function<SourceLocation,
1137                                                         SourceLocation, bool> {
1138    SourceManager &SM;
1139
1140  public:
1141    explicit LocBeforeThanCompare(SourceManager &SM) : SM(SM) { }
1142
1143    bool operator()(SourceLocation LHS, SourceLocation RHS) const {
1144      return SM.isBeforeInTranslationUnit(LHS, RHS);
1145    }
1146  };
1147
1148  /// \brief Determines the order of 2 source locations in the "source location
1149  /// address space".
1150  bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const {
1151    return isBeforeInSLocAddrSpace(LHS, RHS.getOffset());
1152  }
1153
1154  /// \brief Determines the order of a source location and a source location
1155  /// offset in the "source location address space".
1156  ///
1157  /// Note that we always consider source locations loaded from
1158  bool isBeforeInSLocAddrSpace(SourceLocation LHS, unsigned RHS) const {
1159    unsigned LHSOffset = LHS.getOffset();
1160    bool LHSLoaded = LHSOffset >= CurrentLoadedOffset;
1161    bool RHSLoaded = RHS >= CurrentLoadedOffset;
1162    if (LHSLoaded == RHSLoaded)
1163      return LHSOffset < RHS;
1164
1165    return LHSLoaded;
1166  }
1167
1168  // Iterators over FileInfos.
1169  typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
1170      ::const_iterator fileinfo_iterator;
1171  fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
1172  fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
1173  bool hasFileInfo(const FileEntry *File) const {
1174    return FileInfos.find(File) != FileInfos.end();
1175  }
1176
1177  /// PrintStats - Print statistics to stderr.
1178  ///
1179  void PrintStats() const;
1180
1181  /// \brief Get the number of local SLocEntries we have.
1182  unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); }
1183
1184  /// \brief Get a local SLocEntry. This is exposed for indexing.
1185  const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
1186                                             bool *Invalid = 0) const {
1187    assert(Index < LocalSLocEntryTable.size() && "Invalid index");
1188    return LocalSLocEntryTable[Index];
1189  }
1190
1191  /// \brief Get the number of loaded SLocEntries we have.
1192  unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();}
1193
1194  /// \brief Get a loaded SLocEntry. This is exposed for indexing.
1195  const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index, bool *Invalid=0) const {
1196    assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
1197    if (!SLocEntryLoaded[Index])
1198      ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2));
1199    return LoadedSLocEntryTable[Index];
1200  }
1201
1202  const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const {
1203    return getSLocEntryByID(FID.ID);
1204  }
1205
1206  unsigned getNextLocalOffset() const { return NextLocalOffset; }
1207
1208  void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) {
1209    assert(LoadedSLocEntryTable.empty() &&
1210           "Invalidating existing loaded entries");
1211    ExternalSLocEntries = Source;
1212  }
1213
1214  /// \brief Allocate a number of loaded SLocEntries, which will be actually
1215  /// loaded on demand from the external source.
1216  ///
1217  /// NumSLocEntries will be allocated, which occupy a total of TotalSize space
1218  /// in the global source view. The lowest ID and the base offset of the
1219  /// entries will be returned.
1220  std::pair<int, unsigned>
1221  AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize);
1222
1223private:
1224  const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
1225
1226  /// \brief Get the entry with the given unwrapped FileID.
1227  const SrcMgr::SLocEntry &getSLocEntryByID(int ID) const {
1228    assert(ID != -1 && "Using FileID sentinel value");
1229    if (ID < 0)
1230      return getLoadedSLocEntryByID(ID);
1231    return getLocalSLocEntry(static_cast<unsigned>(ID));
1232  }
1233
1234  const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID) const {
1235    return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2));
1236  }
1237
1238  /// createExpansionLoc - Implements the common elements of storing an
1239  /// expansion info struct into the SLocEntry table and producing a source
1240  /// location that refers to it.
1241  SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion,
1242                                        unsigned TokLength,
1243                                        int LoadedID = 0,
1244                                        unsigned LoadedOffset = 0);
1245
1246  /// isOffsetInFileID - Return true if the specified FileID contains the
1247  /// specified SourceLocation offset.  This is a very hot method.
1248  inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
1249    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
1250    // If the entry is after the offset, it can't contain it.
1251    if (SLocOffset < Entry.getOffset()) return false;
1252
1253    // If this is the very last entry then it does.
1254    if (FID.ID == -2)
1255      return true;
1256
1257    // If it is the last local entry, then it does if the location is local.
1258    if (static_cast<unsigned>(FID.ID+1) == LocalSLocEntryTable.size()) {
1259      return SLocOffset < NextLocalOffset;
1260    }
1261
1262    // Otherwise, the entry after it has to not include it. This works for both
1263    // local and loaded entries.
1264    return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
1265  }
1266
1267  /// createFileID - Create a new fileID for the specified ContentCache and
1268  ///  include position.  This works regardless of whether the ContentCache
1269  ///  corresponds to a file or some other input source.
1270  FileID createFileID(const SrcMgr::ContentCache* File,
1271                      SourceLocation IncludePos,
1272                      SrcMgr::CharacteristicKind DirCharacter,
1273                      int LoadedID, unsigned LoadedOffset);
1274
1275  const SrcMgr::ContentCache *
1276    getOrCreateContentCache(const FileEntry *SourceFile);
1277
1278  /// createMemBufferContentCache - Create a new ContentCache for the specified
1279  ///  memory buffer.
1280  const SrcMgr::ContentCache*
1281  createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
1282
1283  FileID getFileIDSlow(unsigned SLocOffset) const;
1284  FileID getFileIDLocal(unsigned SLocOffset) const;
1285  FileID getFileIDLoaded(unsigned SLocOffset) const;
1286
1287  SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const;
1288  SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
1289
1290  std::pair<FileID, unsigned>
1291  getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const;
1292  std::pair<FileID, unsigned>
1293  getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
1294                                   unsigned Offset) const;
1295  void computeMacroArgsCache(SrcMgr::ContentCache *Content, FileID FID);
1296};
1297
1298
1299}  // end namespace clang
1300
1301#endif
1302