Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:11

0001 //===--- StandardLibrary.h --------------------------------------*- 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 /// \file
0010 /// Provides an interface for querying information about C and C++ Standard
0011 /// Library headers and symbols.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H
0016 #define LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H
0017 
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/Hashing.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/Support/raw_ostream.h"
0022 #include <optional>
0023 #include <string>
0024 #include <vector>
0025 
0026 namespace clang {
0027 class Decl;
0028 class NamespaceDecl;
0029 class DeclContext;
0030 namespace tooling {
0031 namespace stdlib {
0032 
0033 class Symbol;
0034 enum class Lang { C = 0, CXX, LastValue = CXX };
0035 
0036 // A standard library header, such as <iostream>
0037 // Lightweight class, in fact just an index into a table.
0038 // C++ and C Library compatibility headers are considered different: e.g.
0039 // "<cstdio>" and "<stdio.h>" (and their symbols) are treated differently.
0040 class Header {
0041 public:
0042   static std::vector<Header> all(Lang L = Lang::CXX);
0043   // Name should contain the angle brackets, e.g. "<vector>".
0044   static std::optional<Header> named(llvm::StringRef Name,
0045                                      Lang Language = Lang::CXX);
0046 
0047   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Header &H) {
0048     return OS << H.name();
0049   }
0050   llvm::StringRef name() const;
0051 
0052 private:
0053   Header(unsigned ID, Lang Language) : ID(ID), Language(Language) {}
0054   unsigned ID;
0055   Lang Language;
0056 
0057   friend Symbol;
0058   friend llvm::DenseMapInfo<Header>;
0059   friend bool operator==(const Header &L, const Header &R) {
0060     return L.ID == R.ID;
0061   }
0062 };
0063 
0064 // A top-level standard library symbol, such as std::vector
0065 // Lightweight class, in fact just an index into a table.
0066 // C++ and C Standard Library symbols are considered distinct: e.g. std::printf
0067 // and ::printf are not treated as the same symbol.
0068 // The symbols do not contain macros right now, we don't have a reliable index
0069 // for them.
0070 class Symbol {
0071 public:
0072   static std::vector<Symbol> all(Lang L = Lang::CXX);
0073   /// \p Scope should have the trailing "::", for example:
0074   /// named("std::chrono::", "system_clock")
0075   static std::optional<Symbol>
0076   named(llvm::StringRef Scope, llvm::StringRef Name, Lang Language = Lang::CXX);
0077 
0078   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
0079     return OS << S.qualifiedName();
0080   }
0081   llvm::StringRef scope() const;
0082   llvm::StringRef name() const;
0083   llvm::StringRef qualifiedName() const;
0084   // The preferred header for this symbol (e.g. the suggested insertion).
0085   std::optional<Header> header() const;
0086   // Some symbols may be provided by multiple headers.
0087   llvm::SmallVector<Header> headers() const;
0088 
0089 private:
0090   Symbol(unsigned ID, Lang Language) : ID(ID), Language(Language) {}
0091   unsigned ID;
0092   Lang Language;
0093 
0094   friend class Recognizer;
0095   friend llvm::DenseMapInfo<Symbol>;
0096   friend bool operator==(const Symbol &L, const Symbol &R) {
0097     return L.ID == R.ID;
0098   }
0099 };
0100 
0101 // A functor to find the stdlib::Symbol associated with a decl.
0102 //
0103 // For non-top-level decls (std::vector<int>::iterator), returns the top-level
0104 // symbol (std::vector).
0105 class Recognizer {
0106 public:
0107   Recognizer();
0108   std::optional<Symbol> operator()(const Decl *D);
0109 
0110 private:
0111   using NSSymbolMap = llvm::DenseMap<llvm::StringRef, unsigned>;
0112   NSSymbolMap *namespaceSymbols(const DeclContext *DC, Lang L);
0113   llvm::DenseMap<const DeclContext *, NSSymbolMap *> NamespaceCache;
0114 };
0115 
0116 } // namespace stdlib
0117 } // namespace tooling
0118 } // namespace clang
0119 
0120 namespace llvm {
0121 
0122 template <> struct DenseMapInfo<clang::tooling::stdlib::Header> {
0123   static inline clang::tooling::stdlib::Header getEmptyKey() {
0124     return clang::tooling::stdlib::Header(-1,
0125                                           clang::tooling::stdlib::Lang::CXX);
0126   }
0127   static inline clang::tooling::stdlib::Header getTombstoneKey() {
0128     return clang::tooling::stdlib::Header(-2,
0129                                           clang::tooling::stdlib::Lang::CXX);
0130   }
0131   static unsigned getHashValue(const clang::tooling::stdlib::Header &H) {
0132     return hash_value(H.ID);
0133   }
0134   static bool isEqual(const clang::tooling::stdlib::Header &LHS,
0135                       const clang::tooling::stdlib::Header &RHS) {
0136     return LHS == RHS;
0137   }
0138 };
0139 
0140 template <> struct DenseMapInfo<clang::tooling::stdlib::Symbol> {
0141   static inline clang::tooling::stdlib::Symbol getEmptyKey() {
0142     return clang::tooling::stdlib::Symbol(-1,
0143                                           clang::tooling::stdlib::Lang::CXX);
0144   }
0145   static inline clang::tooling::stdlib::Symbol getTombstoneKey() {
0146     return clang::tooling::stdlib::Symbol(-2,
0147                                           clang::tooling::stdlib::Lang::CXX);
0148   }
0149   static unsigned getHashValue(const clang::tooling::stdlib::Symbol &S) {
0150     return hash_value(S.ID);
0151   }
0152   static bool isEqual(const clang::tooling::stdlib::Symbol &LHS,
0153                       const clang::tooling::stdlib::Symbol &RHS) {
0154     return LHS == RHS;
0155   }
0156 };
0157 } // namespace llvm
0158 
0159 #endif // LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H