Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:27

0001 //===--- APINotesManager.h - Manage API Notes Files -------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H
0010 #define LLVM_CLANG_APINOTES_APINOTESMANAGER_H
0011 
0012 #include "clang/Basic/SourceLocation.h"
0013 #include "llvm/ADT/ArrayRef.h"
0014 #include "llvm/ADT/DenseMap.h"
0015 #include "llvm/ADT/PointerUnion.h"
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/Support/VersionTuple.h"
0018 #include <memory>
0019 #include <string>
0020 
0021 namespace clang {
0022 
0023 class DirectoryEntry;
0024 class FileEntry;
0025 class LangOptions;
0026 class Module;
0027 class SourceManager;
0028 
0029 namespace api_notes {
0030 
0031 class APINotesReader;
0032 
0033 /// The API notes manager helps find API notes associated with declarations.
0034 ///
0035 /// API notes are externally-provided annotations for declarations that can
0036 /// introduce new attributes (covering availability, nullability of
0037 /// parameters/results, and so on) for specific declarations without directly
0038 /// modifying the headers that contain those declarations.
0039 ///
0040 /// The API notes manager is responsible for finding and loading the
0041 /// external API notes files that correspond to a given header. Its primary
0042 /// operation is \c findAPINotes(), which finds the API notes reader that
0043 /// provides information about the declarations at that location.
0044 class APINotesManager {
0045   using ReaderEntry = llvm::PointerUnion<DirectoryEntryRef, APINotesReader *>;
0046 
0047   SourceManager &SM;
0048 
0049   /// Whether to implicitly search for API notes files based on the
0050   /// source file from which an entity was declared.
0051   bool ImplicitAPINotes;
0052 
0053   /// The Swift version to use when interpreting versioned API notes.
0054   llvm::VersionTuple SwiftVersion;
0055 
0056   enum ReaderKind : unsigned { Public = 0, Private = 1 };
0057 
0058   /// API notes readers for the current module.
0059   ///
0060   /// There can be up to two of these, one for public headers and one
0061   /// for private headers.
0062   ///
0063   /// Not using std::unique_ptr to store these, since the reader pointers are
0064   /// also stored in llvm::PointerUnion below.
0065   APINotesReader *CurrentModuleReaders[2] = {nullptr, nullptr};
0066 
0067   /// A mapping from header file directories to the API notes reader for
0068   /// that directory, or a redirection to another directory entry that may
0069   /// have more information, or NULL to indicate that there is no API notes
0070   /// reader for this directory.
0071   llvm::DenseMap<const DirectoryEntry *, ReaderEntry> Readers;
0072 
0073   /// Load the API notes associated with the given file, whether it is
0074   /// the binary or source form of API notes.
0075   ///
0076   /// \returns the API notes reader for this file, or null if there is
0077   /// a failure.
0078   std::unique_ptr<APINotesReader> loadAPINotes(FileEntryRef APINotesFile);
0079 
0080   /// Load the API notes associated with the given buffer, whether it is
0081   /// the binary or source form of API notes.
0082   ///
0083   /// \returns the API notes reader for this file, or null if there is
0084   /// a failure.
0085   std::unique_ptr<APINotesReader> loadAPINotes(StringRef Buffer);
0086 
0087   /// Load the given API notes file for the given header directory.
0088   ///
0089   /// \param HeaderDir The directory at which we
0090   ///
0091   /// \returns true if an error occurred.
0092   bool loadAPINotes(const DirectoryEntry *HeaderDir, FileEntryRef APINotesFile);
0093 
0094   /// Look for API notes in the given directory.
0095   ///
0096   /// This might find either a binary or source API notes.
0097   OptionalFileEntryRef findAPINotesFile(DirectoryEntryRef Directory,
0098                                         StringRef FileName,
0099                                         bool WantPublic = true);
0100 
0101   /// Attempt to load API notes for the given framework. A framework will have
0102   /// the API notes file under either {FrameworkPath}/APINotes,
0103   /// {FrameworkPath}/Headers or {FrameworkPath}/PrivateHeaders, while a
0104   /// library will have the API notes simply in its directory.
0105   ///
0106   /// \param FrameworkPath The path to the framework.
0107   /// \param Public Whether to load the public API notes. Otherwise, attempt
0108   /// to load the private API notes.
0109   ///
0110   /// \returns the header directory entry (e.g., for Headers or PrivateHeaders)
0111   /// for which the API notes were successfully loaded, or NULL if API notes
0112   /// could not be loaded for any reason.
0113   OptionalDirectoryEntryRef loadFrameworkAPINotes(llvm::StringRef FrameworkPath,
0114                                                   llvm::StringRef FrameworkName,
0115                                                   bool Public);
0116 
0117 public:
0118   APINotesManager(SourceManager &SM, const LangOptions &LangOpts);
0119   ~APINotesManager();
0120 
0121   /// Set the Swift version to use when filtering API notes.
0122   void setSwiftVersion(llvm::VersionTuple Version) {
0123     this->SwiftVersion = Version;
0124   }
0125 
0126   /// Load the API notes for the current module.
0127   ///
0128   /// \param M The current module.
0129   /// \param LookInModule Whether to look inside the module itself.
0130   /// \param SearchPaths The paths in which we should search for API notes
0131   /// for the current module.
0132   ///
0133   /// \returns true if API notes were successfully loaded, \c false otherwise.
0134   bool loadCurrentModuleAPINotes(Module *M, bool LookInModule,
0135                                  ArrayRef<std::string> SearchPaths);
0136 
0137   /// Get FileEntry for the APINotes of the module that is currently being
0138   /// compiled.
0139   ///
0140   /// \param M The current module.
0141   /// \param LookInModule Whether to look inside the directory of the current
0142   /// module.
0143   /// \param SearchPaths The paths in which we should search for API
0144   /// notes for the current module.
0145   ///
0146   /// \returns a vector of FileEntry where APINotes files are.
0147   llvm::SmallVector<FileEntryRef, 2>
0148   getCurrentModuleAPINotes(Module *M, bool LookInModule,
0149                            ArrayRef<std::string> SearchPaths);
0150 
0151   /// Load Compiled API notes for current module.
0152   ///
0153   /// \param Buffers Array of compiled API notes.
0154   ///
0155   /// \returns true if API notes were successfully loaded, \c false otherwise.
0156   bool loadCurrentModuleAPINotesFromBuffer(ArrayRef<StringRef> Buffers);
0157 
0158   /// Retrieve the set of API notes readers for the current module.
0159   ArrayRef<APINotesReader *> getCurrentModuleReaders() const {
0160     bool HasPublic = CurrentModuleReaders[ReaderKind::Public];
0161     bool HasPrivate = CurrentModuleReaders[ReaderKind::Private];
0162     assert((!HasPrivate || HasPublic) && "private module requires public module");
0163     if (!HasPrivate && !HasPublic)
0164       return {};
0165     return ArrayRef(CurrentModuleReaders).slice(0, HasPrivate ? 2 : 1);
0166   }
0167 
0168   /// Find the API notes readers that correspond to the given source location.
0169   llvm::SmallVector<APINotesReader *, 2> findAPINotes(SourceLocation Loc);
0170 };
0171 
0172 } // end namespace api_notes
0173 } // end namespace clang
0174 
0175 #endif