1//===--- APINotesReader.h - API Notes Reader --------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the \c APINotesReader class that reads source API notes
10// data providing additional information about source code as a separate input,
11// such as the non-nil/nilable annotations for method parameters.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_APINOTES_READER_H
16#define LLVM_CLANG_APINOTES_READER_H
17
18#include "clang/APINotes/Types.h"
19#include "llvm/Support/MemoryBuffer.h"
20#include "llvm/Support/VersionTuple.h"
21#include <memory>
22
23namespace clang {
24namespace api_notes {
25
26/// A class that reads API notes data from a binary file that was written by
27/// the \c APINotesWriter.
28class APINotesReader {
29  class Implementation;
30  std::unique_ptr<Implementation> Implementation;
31
32  APINotesReader(llvm::MemoryBuffer *InputBuffer,
33                 llvm::VersionTuple SwiftVersion, bool &Failed);
34
35public:
36  /// Create a new API notes reader from the given member buffer, which
37  /// contains the contents of a binary API notes file.
38  ///
39  /// \returns the new API notes reader, or null if an error occurred.
40  static std::unique_ptr<APINotesReader>
41  Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
42         llvm::VersionTuple SwiftVersion);
43
44  ~APINotesReader();
45
46  APINotesReader(const APINotesReader &) = delete;
47  APINotesReader &operator=(const APINotesReader &) = delete;
48
49  /// Captures the completed versioned information for a particular part of
50  /// API notes, including both unversioned API notes and each versioned API
51  /// note for that particular entity.
52  template <typename T> class VersionedInfo {
53    /// The complete set of results.
54    llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results;
55
56    /// The index of the result that is the "selected" set based on the desired
57    /// Swift version, or null if nothing matched.
58    std::optional<unsigned> Selected;
59
60  public:
61    /// Form an empty set of versioned information.
62    VersionedInfo(std::nullopt_t) : Selected(std::nullopt) {}
63
64    /// Form a versioned info set given the desired version and a set of
65    /// results.
66    VersionedInfo(
67        llvm::VersionTuple Version,
68        llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results);
69
70    /// Retrieve the selected index in the result set.
71    std::optional<unsigned> getSelected() const { return Selected; }
72
73    /// Return the number of versioned results we know about.
74    unsigned size() const { return Results.size(); }
75
76    /// Access all versioned results.
77    const std::pair<llvm::VersionTuple, T> *begin() const {
78      assert(!Results.empty());
79      return Results.begin();
80    }
81    const std::pair<llvm::VersionTuple, T> *end() const {
82      return Results.end();
83    }
84
85    /// Access a specific versioned result.
86    const std::pair<llvm::VersionTuple, T> &operator[](unsigned index) const {
87      assert(index < Results.size());
88      return Results[index];
89    }
90  };
91
92  /// Look for the context ID of the given Objective-C class.
93  ///
94  /// \param Name The name of the class we're looking for.
95  ///
96  /// \returns The ID, if known.
97  std::optional<ContextID> lookupObjCClassID(llvm::StringRef Name);
98
99  /// Look for information regarding the given Objective-C class.
100  ///
101  /// \param Name The name of the class we're looking for.
102  ///
103  /// \returns The information about the class, if known.
104  VersionedInfo<ObjCContextInfo> lookupObjCClassInfo(llvm::StringRef Name);
105
106  /// Look for the context ID of the given Objective-C protocol.
107  ///
108  /// \param Name The name of the protocol we're looking for.
109  ///
110  /// \returns The ID of the protocol, if known.
111  std::optional<ContextID> lookupObjCProtocolID(llvm::StringRef Name);
112
113  /// Look for information regarding the given Objective-C protocol.
114  ///
115  /// \param Name The name of the protocol we're looking for.
116  ///
117  /// \returns The information about the protocol, if known.
118  VersionedInfo<ObjCContextInfo> lookupObjCProtocolInfo(llvm::StringRef Name);
119
120  /// Look for information regarding the given Objective-C property in
121  /// the given context.
122  ///
123  /// \param CtxID The ID that references the context we are looking for.
124  /// \param Name The name of the property we're looking for.
125  /// \param IsInstance Whether we are looking for an instance property (vs.
126  /// a class property).
127  ///
128  /// \returns Information about the property, if known.
129  VersionedInfo<ObjCPropertyInfo>
130  lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance);
131
132  /// Look for information regarding the given Objective-C method in
133  /// the given context.
134  ///
135  /// \param CtxID The ID that references the context we are looking for.
136  /// \param Selector The selector naming the method we're looking for.
137  /// \param IsInstanceMethod Whether we are looking for an instance method.
138  ///
139  /// \returns Information about the method, if known.
140  VersionedInfo<ObjCMethodInfo> lookupObjCMethod(ContextID CtxID,
141                                                 ObjCSelectorRef Selector,
142                                                 bool IsInstanceMethod);
143
144  /// Look for information regarding the given global variable.
145  ///
146  /// \param Name The name of the global variable.
147  ///
148  /// \returns information about the global variable, if known.
149  VersionedInfo<GlobalVariableInfo>
150  lookupGlobalVariable(llvm::StringRef Name,
151                       std::optional<Context> Ctx = std::nullopt);
152
153  /// Look for information regarding the given global function.
154  ///
155  /// \param Name The name of the global function.
156  ///
157  /// \returns information about the global function, if known.
158  VersionedInfo<GlobalFunctionInfo>
159  lookupGlobalFunction(llvm::StringRef Name,
160                       std::optional<Context> Ctx = std::nullopt);
161
162  /// Look for information regarding the given enumerator.
163  ///
164  /// \param Name The name of the enumerator.
165  ///
166  /// \returns information about the enumerator, if known.
167  VersionedInfo<EnumConstantInfo> lookupEnumConstant(llvm::StringRef Name);
168
169  /// Look for information regarding the given tag
170  /// (struct/union/enum/C++ class).
171  ///
172  /// \param Name The name of the tag.
173  ///
174  /// \returns information about the tag, if known.
175  VersionedInfo<TagInfo> lookupTag(llvm::StringRef Name,
176                                   std::optional<Context> Ctx = std::nullopt);
177
178  /// Look for information regarding the given typedef.
179  ///
180  /// \param Name The name of the typedef.
181  ///
182  /// \returns information about the typedef, if known.
183  VersionedInfo<TypedefInfo>
184  lookupTypedef(llvm::StringRef Name,
185                std::optional<Context> Ctx = std::nullopt);
186
187  /// Look for the context ID of the given C++ namespace.
188  ///
189  /// \param Name The name of the class we're looking for.
190  ///
191  /// \returns The ID, if known.
192  std::optional<ContextID>
193  lookupNamespaceID(llvm::StringRef Name,
194                    std::optional<ContextID> ParentNamespaceID = std::nullopt);
195};
196
197} // end namespace api_notes
198} // end namespace clang
199
200#endif // LLVM_CLANG_APINOTES_READER_H
201