15f757f3fSDimitry Andric //===--- APINotesReader.h - API Notes Reader --------------------*- C++ -*-===// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric // 95f757f3fSDimitry Andric // This file defines the \c APINotesReader class that reads source API notes 105f757f3fSDimitry Andric // data providing additional information about source code as a separate input, 115f757f3fSDimitry Andric // such as the non-nil/nilable annotations for method parameters. 125f757f3fSDimitry Andric // 135f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 145f757f3fSDimitry Andric 155f757f3fSDimitry Andric #ifndef LLVM_CLANG_APINOTES_READER_H 165f757f3fSDimitry Andric #define LLVM_CLANG_APINOTES_READER_H 175f757f3fSDimitry Andric 185f757f3fSDimitry Andric #include "clang/APINotes/Types.h" 195f757f3fSDimitry Andric #include "llvm/Support/MemoryBuffer.h" 205f757f3fSDimitry Andric #include "llvm/Support/VersionTuple.h" 215f757f3fSDimitry Andric #include <memory> 225f757f3fSDimitry Andric 235f757f3fSDimitry Andric namespace clang { 245f757f3fSDimitry Andric namespace api_notes { 255f757f3fSDimitry Andric 265f757f3fSDimitry Andric /// A class that reads API notes data from a binary file that was written by 275f757f3fSDimitry Andric /// the \c APINotesWriter. 285f757f3fSDimitry Andric class APINotesReader { 295f757f3fSDimitry Andric class Implementation; 305f757f3fSDimitry Andric std::unique_ptr<Implementation> Implementation; 315f757f3fSDimitry Andric 325f757f3fSDimitry Andric APINotesReader(llvm::MemoryBuffer *InputBuffer, 335f757f3fSDimitry Andric llvm::VersionTuple SwiftVersion, bool &Failed); 345f757f3fSDimitry Andric 355f757f3fSDimitry Andric public: 365f757f3fSDimitry Andric /// Create a new API notes reader from the given member buffer, which 375f757f3fSDimitry Andric /// contains the contents of a binary API notes file. 385f757f3fSDimitry Andric /// 395f757f3fSDimitry Andric /// \returns the new API notes reader, or null if an error occurred. 405f757f3fSDimitry Andric static std::unique_ptr<APINotesReader> 415f757f3fSDimitry Andric Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer, 425f757f3fSDimitry Andric llvm::VersionTuple SwiftVersion); 435f757f3fSDimitry Andric 445f757f3fSDimitry Andric ~APINotesReader(); 455f757f3fSDimitry Andric 465f757f3fSDimitry Andric APINotesReader(const APINotesReader &) = delete; 475f757f3fSDimitry Andric APINotesReader &operator=(const APINotesReader &) = delete; 485f757f3fSDimitry Andric 495f757f3fSDimitry Andric /// Captures the completed versioned information for a particular part of 505f757f3fSDimitry Andric /// API notes, including both unversioned API notes and each versioned API 515f757f3fSDimitry Andric /// note for that particular entity. 525f757f3fSDimitry Andric template <typename T> class VersionedInfo { 535f757f3fSDimitry Andric /// The complete set of results. 545f757f3fSDimitry Andric llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results; 555f757f3fSDimitry Andric 565f757f3fSDimitry Andric /// The index of the result that is the "selected" set based on the desired 575f757f3fSDimitry Andric /// Swift version, or null if nothing matched. 585f757f3fSDimitry Andric std::optional<unsigned> Selected; 595f757f3fSDimitry Andric 605f757f3fSDimitry Andric public: 615f757f3fSDimitry Andric /// Form an empty set of versioned information. VersionedInfo(std::nullopt_t)625f757f3fSDimitry Andric VersionedInfo(std::nullopt_t) : Selected(std::nullopt) {} 635f757f3fSDimitry Andric 645f757f3fSDimitry Andric /// Form a versioned info set given the desired version and a set of 655f757f3fSDimitry Andric /// results. 665f757f3fSDimitry Andric VersionedInfo( 675f757f3fSDimitry Andric llvm::VersionTuple Version, 685f757f3fSDimitry Andric llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results); 695f757f3fSDimitry Andric 705f757f3fSDimitry Andric /// Retrieve the selected index in the result set. getSelected()715f757f3fSDimitry Andric std::optional<unsigned> getSelected() const { return Selected; } 725f757f3fSDimitry Andric 735f757f3fSDimitry Andric /// Return the number of versioned results we know about. size()745f757f3fSDimitry Andric unsigned size() const { return Results.size(); } 755f757f3fSDimitry Andric 765f757f3fSDimitry Andric /// Access all versioned results. begin()775f757f3fSDimitry Andric const std::pair<llvm::VersionTuple, T> *begin() const { 785f757f3fSDimitry Andric assert(!Results.empty()); 795f757f3fSDimitry Andric return Results.begin(); 805f757f3fSDimitry Andric } end()815f757f3fSDimitry Andric const std::pair<llvm::VersionTuple, T> *end() const { 825f757f3fSDimitry Andric return Results.end(); 835f757f3fSDimitry Andric } 845f757f3fSDimitry Andric 855f757f3fSDimitry Andric /// Access a specific versioned result. 865f757f3fSDimitry Andric const std::pair<llvm::VersionTuple, T> &operator[](unsigned index) const { 875f757f3fSDimitry Andric assert(index < Results.size()); 885f757f3fSDimitry Andric return Results[index]; 895f757f3fSDimitry Andric } 905f757f3fSDimitry Andric }; 915f757f3fSDimitry Andric 925f757f3fSDimitry Andric /// Look for the context ID of the given Objective-C class. 935f757f3fSDimitry Andric /// 945f757f3fSDimitry Andric /// \param Name The name of the class we're looking for. 955f757f3fSDimitry Andric /// 965f757f3fSDimitry Andric /// \returns The ID, if known. 975f757f3fSDimitry Andric std::optional<ContextID> lookupObjCClassID(llvm::StringRef Name); 985f757f3fSDimitry Andric 995f757f3fSDimitry Andric /// Look for information regarding the given Objective-C class. 1005f757f3fSDimitry Andric /// 1015f757f3fSDimitry Andric /// \param Name The name of the class we're looking for. 1025f757f3fSDimitry Andric /// 1035f757f3fSDimitry Andric /// \returns The information about the class, if known. 104*0fca6ea1SDimitry Andric VersionedInfo<ContextInfo> lookupObjCClassInfo(llvm::StringRef Name); 1055f757f3fSDimitry Andric 1065f757f3fSDimitry Andric /// Look for the context ID of the given Objective-C protocol. 1075f757f3fSDimitry Andric /// 1085f757f3fSDimitry Andric /// \param Name The name of the protocol we're looking for. 1095f757f3fSDimitry Andric /// 1105f757f3fSDimitry Andric /// \returns The ID of the protocol, if known. 1115f757f3fSDimitry Andric std::optional<ContextID> lookupObjCProtocolID(llvm::StringRef Name); 1125f757f3fSDimitry Andric 1135f757f3fSDimitry Andric /// Look for information regarding the given Objective-C protocol. 1145f757f3fSDimitry Andric /// 1155f757f3fSDimitry Andric /// \param Name The name of the protocol we're looking for. 1165f757f3fSDimitry Andric /// 1175f757f3fSDimitry Andric /// \returns The information about the protocol, if known. 118*0fca6ea1SDimitry Andric VersionedInfo<ContextInfo> lookupObjCProtocolInfo(llvm::StringRef Name); 1195f757f3fSDimitry Andric 1205f757f3fSDimitry Andric /// Look for information regarding the given Objective-C property in 1215f757f3fSDimitry Andric /// the given context. 1225f757f3fSDimitry Andric /// 1235f757f3fSDimitry Andric /// \param CtxID The ID that references the context we are looking for. 1245f757f3fSDimitry Andric /// \param Name The name of the property we're looking for. 1255f757f3fSDimitry Andric /// \param IsInstance Whether we are looking for an instance property (vs. 1265f757f3fSDimitry Andric /// a class property). 1275f757f3fSDimitry Andric /// 1285f757f3fSDimitry Andric /// \returns Information about the property, if known. 1295f757f3fSDimitry Andric VersionedInfo<ObjCPropertyInfo> 1305f757f3fSDimitry Andric lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance); 1315f757f3fSDimitry Andric 1325f757f3fSDimitry Andric /// Look for information regarding the given Objective-C method in 1335f757f3fSDimitry Andric /// the given context. 1345f757f3fSDimitry Andric /// 1355f757f3fSDimitry Andric /// \param CtxID The ID that references the context we are looking for. 1365f757f3fSDimitry Andric /// \param Selector The selector naming the method we're looking for. 1375f757f3fSDimitry Andric /// \param IsInstanceMethod Whether we are looking for an instance method. 1385f757f3fSDimitry Andric /// 1395f757f3fSDimitry Andric /// \returns Information about the method, if known. 1405f757f3fSDimitry Andric VersionedInfo<ObjCMethodInfo> lookupObjCMethod(ContextID CtxID, 1415f757f3fSDimitry Andric ObjCSelectorRef Selector, 1425f757f3fSDimitry Andric bool IsInstanceMethod); 1435f757f3fSDimitry Andric 144*0fca6ea1SDimitry Andric /// Look for information regarding the given C++ method in the given C++ tag 145*0fca6ea1SDimitry Andric /// context. 146*0fca6ea1SDimitry Andric /// 147*0fca6ea1SDimitry Andric /// \param CtxID The ID that references the parent context, i.e. a C++ tag. 148*0fca6ea1SDimitry Andric /// \param Name The name of the C++ method we're looking for. 149*0fca6ea1SDimitry Andric /// 150*0fca6ea1SDimitry Andric /// \returns Information about the method, if known. 151*0fca6ea1SDimitry Andric VersionedInfo<CXXMethodInfo> lookupCXXMethod(ContextID CtxID, 152*0fca6ea1SDimitry Andric llvm::StringRef Name); 153*0fca6ea1SDimitry Andric 1545f757f3fSDimitry Andric /// Look for information regarding the given global variable. 1555f757f3fSDimitry Andric /// 1565f757f3fSDimitry Andric /// \param Name The name of the global variable. 1575f757f3fSDimitry Andric /// 1585f757f3fSDimitry Andric /// \returns information about the global variable, if known. 1595f757f3fSDimitry Andric VersionedInfo<GlobalVariableInfo> 1605f757f3fSDimitry Andric lookupGlobalVariable(llvm::StringRef Name, 1615f757f3fSDimitry Andric std::optional<Context> Ctx = std::nullopt); 1625f757f3fSDimitry Andric 1635f757f3fSDimitry Andric /// Look for information regarding the given global function. 1645f757f3fSDimitry Andric /// 1655f757f3fSDimitry Andric /// \param Name The name of the global function. 1665f757f3fSDimitry Andric /// 1675f757f3fSDimitry Andric /// \returns information about the global function, if known. 1685f757f3fSDimitry Andric VersionedInfo<GlobalFunctionInfo> 1695f757f3fSDimitry Andric lookupGlobalFunction(llvm::StringRef Name, 1705f757f3fSDimitry Andric std::optional<Context> Ctx = std::nullopt); 1715f757f3fSDimitry Andric 1725f757f3fSDimitry Andric /// Look for information regarding the given enumerator. 1735f757f3fSDimitry Andric /// 1745f757f3fSDimitry Andric /// \param Name The name of the enumerator. 1755f757f3fSDimitry Andric /// 1765f757f3fSDimitry Andric /// \returns information about the enumerator, if known. 1775f757f3fSDimitry Andric VersionedInfo<EnumConstantInfo> lookupEnumConstant(llvm::StringRef Name); 1785f757f3fSDimitry Andric 179*0fca6ea1SDimitry Andric /// Look for the context ID of the given C++ tag. 180*0fca6ea1SDimitry Andric /// 181*0fca6ea1SDimitry Andric /// \param Name The name of the tag we're looking for. 182*0fca6ea1SDimitry Andric /// \param ParentCtx The context in which this tag is declared, e.g. a C++ 183*0fca6ea1SDimitry Andric /// namespace. 184*0fca6ea1SDimitry Andric /// 185*0fca6ea1SDimitry Andric /// \returns The ID, if known. 186*0fca6ea1SDimitry Andric std::optional<ContextID> 187*0fca6ea1SDimitry Andric lookupTagID(llvm::StringRef Name, 188*0fca6ea1SDimitry Andric std::optional<Context> ParentCtx = std::nullopt); 189*0fca6ea1SDimitry Andric 1905f757f3fSDimitry Andric /// Look for information regarding the given tag 1915f757f3fSDimitry Andric /// (struct/union/enum/C++ class). 1925f757f3fSDimitry Andric /// 1935f757f3fSDimitry Andric /// \param Name The name of the tag. 1945f757f3fSDimitry Andric /// 1955f757f3fSDimitry Andric /// \returns information about the tag, if known. 1965f757f3fSDimitry Andric VersionedInfo<TagInfo> lookupTag(llvm::StringRef Name, 1975f757f3fSDimitry Andric std::optional<Context> Ctx = std::nullopt); 1985f757f3fSDimitry Andric 1995f757f3fSDimitry Andric /// Look for information regarding the given typedef. 2005f757f3fSDimitry Andric /// 2015f757f3fSDimitry Andric /// \param Name The name of the typedef. 2025f757f3fSDimitry Andric /// 2035f757f3fSDimitry Andric /// \returns information about the typedef, if known. 2045f757f3fSDimitry Andric VersionedInfo<TypedefInfo> 2055f757f3fSDimitry Andric lookupTypedef(llvm::StringRef Name, 2065f757f3fSDimitry Andric std::optional<Context> Ctx = std::nullopt); 2075f757f3fSDimitry Andric 2085f757f3fSDimitry Andric /// Look for the context ID of the given C++ namespace. 2095f757f3fSDimitry Andric /// 2105f757f3fSDimitry Andric /// \param Name The name of the class we're looking for. 2115f757f3fSDimitry Andric /// 2125f757f3fSDimitry Andric /// \returns The ID, if known. 2135f757f3fSDimitry Andric std::optional<ContextID> 2145f757f3fSDimitry Andric lookupNamespaceID(llvm::StringRef Name, 2155f757f3fSDimitry Andric std::optional<ContextID> ParentNamespaceID = std::nullopt); 2165f757f3fSDimitry Andric }; 2175f757f3fSDimitry Andric 2185f757f3fSDimitry Andric } // end namespace api_notes 2195f757f3fSDimitry Andric } // end namespace clang 2205f757f3fSDimitry Andric 2215f757f3fSDimitry Andric #endif // LLVM_CLANG_APINOTES_READER_H 222