12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/ADT/DenseSet.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Casting.h"
25using NSSymbolMap = llvm::DenseMap<llvm::StringRef, unsigned>;
28struct SymbolHeaderMapping {
31 llvm::DenseMap<llvm::StringRef, unsigned> *
HeaderIDs;
39 StringRef scope()
const {
return StringRef(
Data,
ScopeLen); }
40 StringRef
name()
const {
return StringRef(Data + ScopeLen, NameLen); }
41 StringRef qualifiedName()
const {
42 return StringRef(Data, ScopeLen + NameLen);
51static SymbolHeaderMapping
59#define SYMBOL(Name, NS, Header) #NS #Name,
62 static constexpr const char *CSymbols[] = {
69 static constexpr const char *CXXSymbols[] = {
83 SymbolHeaderMapping *Mapping =
new SymbolHeaderMapping();
87 Mapping->SymbolCount = SymCount;
88 Mapping->SymbolNames =
89 new std::remove_reference_t<
decltype(*Mapping->SymbolNames)>[SymCount];
90 Mapping->SymbolHeaderIDs =
new std::remove_reference_t<
91 decltype(*Mapping->SymbolHeaderIDs)>[SymCount];
92 Mapping->NamespaceSymbols =
93 new std::remove_reference_t<
decltype(*Mapping->NamespaceSymbols)>;
95 new std::remove_reference_t<
decltype(*Mapping->HeaderIDs)>;
96 auto AddNS = [&](llvm::StringRef NS) -> NSSymbolMap & {
97 auto R = Mapping->NamespaceSymbols->try_emplace(NS,
nullptr);
99 R.first->second =
new NSSymbolMap();
100 return *R.first->second;
103 auto AddHeader = [&](llvm::StringRef
Header) ->
unsigned {
104 return Mapping->HeaderIDs->try_emplace(
Header, Mapping->HeaderIDs->size())
108 auto Add = [&, SymIndex(-1)](llvm::StringRef QName,
unsigned NSLen,
109 llvm::StringRef HeaderName)
mutable {
112 if (QName.take_front(NSLen) ==
"None") {
113 QName = QName.drop_front(NSLen);
118 Mapping->SymbolNames[SymIndex].qualifiedName() == QName) {
120 assert(llvm::none_of(
llvm::ArrayRef(Mapping->SymbolNames, SymIndex),
121 [&QName](
const SymbolHeaderMapping::SymbolName &S) {
122 return S.qualifiedName() == QName;
124 "The symbol has been added before, make sure entries in the .inc "
125 "file are grouped by symbol name!");
130 Mapping->SymbolNames[SymIndex] = {
131 QName.data(), NSLen,
static_cast<unsigned int>(QName.size() - NSLen)};
132 if (!HeaderName.empty())
133 Mapping->SymbolHeaderIDs[SymIndex].push_back(AddHeader(HeaderName));
135 NSSymbolMap &NSSymbols = AddNS(QName.take_front(NSLen));
136 NSSymbols.try_emplace(QName.drop_front(NSLen), SymIndex);
142 const char *HeaderName;
144#define SYMBOL(Name, NS, Header) \
145 {#NS #Name, static_cast<decltype(Symbol::NSLen)>(StringRef(#NS).size()), \
149 static constexpr Symbol CSymbols[] = {
152 for (
const Symbol &S : CSymbols)
153 Add(S.QName, S.NSLen, S.HeaderName);
157 static constexpr Symbol CXXSymbols[] = {
162 for (
const Symbol &S : CXXSymbols)
163 Add(S.QName, S.NSLen, S.HeaderName);
169 Mapping->HeaderNames =
new llvm::StringRef[Mapping->HeaderIDs->size()];
170 for (
const auto &E : *Mapping->HeaderIDs)
171 Mapping->HeaderNames[E.second] = E.first;
177 static int Dummy = []() {
187 std::vector<Header>
Result;
189 Result.reserve(Mapping->HeaderIDs->size());
190 for (
unsigned I = 0, E = Mapping->HeaderIDs->size(); I < E; ++I)
197 auto It = Mapping->HeaderIDs->find(Name);
198 if (It == Mapping->HeaderIDs->end())
200 return Header(It->second, L);
208 std::vector<Symbol>
Result;
210 Result.reserve(Mapping->SymbolCount);
211 for (
unsigned I = 0, E = Mapping->SymbolCount; I < E; ++I)
228 if (NSSymbolMap *NSSymbols =
230 auto It = NSSymbols->find(Name);
231 if (It != NSSymbols->end())
232 return Symbol(It->second, L);
251NSSymbolMap *Recognizer::namespaceSymbols(
const DeclContext *DC,
Lang L) {
255 auto It = NamespaceCache.find(DC);
256 if (It != NamespaceCache.end())
259 NSSymbolMap *
Result = [&]() -> NSSymbolMap * {
264 for (
const auto *ND = D; ND;
265 ND = llvm::dyn_cast_or_null<NamespaceDecl>(ND->getParent()))
266 if (!ND->isInlineNamespace() && !ND->isAnonymousNamespace())
270 NamespaceCache.try_emplace(D,
Result);
292 IntermediateDecl.push_back(DC);
295 NSSymbolMap *Symbols = namespaceSymbols(DC, L);
299 llvm::StringRef Name = [&]() -> llvm::StringRef {
300 for (
const auto *SymDC : llvm::reverse(IntermediateDecl)) {
303 return II->getName();
307 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
308 if (
const auto *II = ND->getIdentifier())
309 return II->getName();
315 auto It = Symbols->find(Name);
316 if (It == Symbols->end())
318 return Symbol(It->second, L);
Defines the clang::LangOptions interface.
llvm::DenseMap< llvm::StringRef, NSSymbolMap * > * NamespaceSymbols
llvm::StringRef * HeaderNames
struct clang::tooling::stdlib::@1902::SymbolHeaderMapping::SymbolName * SymbolNames
llvm::SmallVector< unsigned > * SymbolHeaderIDs
llvm::DenseMap< llvm::StringRef, unsigned > * HeaderIDs
Provides an interface for querying information about C and C++ Standard Library headers and symbols.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
Decl::Kind getDeclKind() const
Decl - This represents one declaration (or definition), e.g.
DeclContext * getDeclContext()
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isEmpty() const
Evaluates true when this declaration name is empty.
static bool classofKind(Kind K)
Represent a C++ namespace.
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
Scope - A scope is a transient data structure that is used while parsing the program.
The JSON file list parser is used to communicate input to InstallAPI.
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.