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) Set.insert(#NS #Name);
75 SymbolHeaderMapping *Mapping =
new SymbolHeaderMapping();
79 Mapping->SymbolCount = SymCount;
80 Mapping->SymbolNames =
81 new std::remove_reference_t<
decltype(*Mapping->SymbolNames)>[SymCount];
82 Mapping->SymbolHeaderIDs =
new std::remove_reference_t<
83 decltype(*Mapping->SymbolHeaderIDs)>[SymCount];
84 Mapping->NamespaceSymbols =
85 new std::remove_reference_t<
decltype(*Mapping->NamespaceSymbols)>;
87 new std::remove_reference_t<
decltype(*Mapping->HeaderIDs)>;
88 auto AddNS = [&](llvm::StringRef NS) -> NSSymbolMap & {
89 auto R = Mapping->NamespaceSymbols->try_emplace(NS,
nullptr);
91 R.first->second =
new NSSymbolMap();
92 return *R.first->second;
95 auto AddHeader = [&](llvm::StringRef
Header) ->
unsigned {
96 return Mapping->HeaderIDs->try_emplace(
Header, Mapping->HeaderIDs->size())
100 auto Add = [&, SymIndex(-1)](llvm::StringRef QName,
unsigned NSLen,
101 llvm::StringRef HeaderName)
mutable {
104 if (QName.take_front(NSLen) ==
"None") {
105 QName = QName.drop_front(NSLen);
110 Mapping->SymbolNames[SymIndex].qualifiedName() == QName) {
112 assert(llvm::none_of(
llvm::ArrayRef(Mapping->SymbolNames, SymIndex),
113 [&QName](
const SymbolHeaderMapping::SymbolName &S) {
114 return S.qualifiedName() == QName;
116 "The symbol has been added before, make sure entries in the .inc "
117 "file are grouped by symbol name!");
122 Mapping->SymbolNames[SymIndex] = {
123 QName.data(), NSLen,
static_cast<unsigned int>(QName.size() - NSLen)};
124 if (!HeaderName.empty())
125 Mapping->SymbolHeaderIDs[SymIndex].push_back(AddHeader(HeaderName));
127 NSSymbolMap &NSSymbols = AddNS(QName.take_front(NSLen));
128 NSSymbols.try_emplace(QName.drop_front(NSLen), SymIndex);
130#define SYMBOL(Name, NS, Header) Add(#NS #Name, strlen(#NS), #Header);
143 Mapping->HeaderNames =
new llvm::StringRef[Mapping->HeaderIDs->size()];
144 for (
const auto &E : *Mapping->HeaderIDs)
145 Mapping->HeaderNames[E.second] = E.first;
151 static int Dummy = []() {
161 std::vector<Header>
Result;
163 Result.reserve(Mapping->HeaderIDs->size());
164 for (
unsigned I = 0, E = Mapping->HeaderIDs->size(); I < E; ++I)
171 auto It = Mapping->HeaderIDs->find(Name);
172 if (It == Mapping->HeaderIDs->end())
174 return Header(It->second, L);
182 std::vector<Symbol>
Result;
184 Result.reserve(Mapping->SymbolCount);
185 for (
unsigned I = 0, E = Mapping->SymbolCount; I < E; ++I)
202 if (NSSymbolMap *NSSymbols =
204 auto It = NSSymbols->find(Name);
205 if (It != NSSymbols->end())
206 return Symbol(It->second, L);
225NSSymbolMap *Recognizer::namespaceSymbols(
const DeclContext *DC,
Lang L) {
229 auto It = NamespaceCache.find(DC);
230 if (It != NamespaceCache.end())
233 NSSymbolMap *
Result = [&]() -> NSSymbolMap * {
238 for (
const auto *ND = D; ND;
239 ND = llvm::dyn_cast_or_null<NamespaceDecl>(ND->getParent()))
240 if (!ND->isInlineNamespace() && !ND->isAnonymousNamespace())
244 NamespaceCache.try_emplace(D,
Result);
266 IntermediateDecl.push_back(DC);
269 NSSymbolMap *Symbols = namespaceSymbols(DC, L);
273 llvm::StringRef Name = [&]() -> llvm::StringRef {
274 for (
const auto *SymDC : llvm::reverse(IntermediateDecl)) {
277 return II->getName();
281 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
282 if (
const auto *II = ND->getIdentifier())
283 return II->getName();
289 auto It = Symbols->find(Name);
290 if (It == Symbols->end())
292 return Symbol(It->second, L);
Defines the clang::LangOptions interface.
struct clang::tooling::stdlib::@1848::SymbolHeaderMapping::SymbolName * SymbolNames
llvm::DenseMap< llvm::StringRef, NSSymbolMap * > * NamespaceSymbols
llvm::StringRef * HeaderNames
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.
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.