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[] = {
70 static constexpr const char *CXXSymbols[] = {
80 return llvm::DenseSet<StringRef>(Symbols.begin(), Symbols.end()).size();
84 SymbolHeaderMapping *Mapping =
new SymbolHeaderMapping();
88 Mapping->SymbolCount = SymCount;
89 Mapping->SymbolNames =
90 new std::remove_reference_t<
decltype(*Mapping->SymbolNames)>[SymCount];
91 Mapping->SymbolHeaderIDs =
new std::remove_reference_t<
92 decltype(*Mapping->SymbolHeaderIDs)>[SymCount];
93 Mapping->NamespaceSymbols =
94 new std::remove_reference_t<
decltype(*Mapping->NamespaceSymbols)>;
96 new std::remove_reference_t<
decltype(*Mapping->HeaderIDs)>;
97 auto AddNS = [&](llvm::StringRef NS) -> NSSymbolMap & {
98 auto R = Mapping->NamespaceSymbols->try_emplace(NS,
nullptr);
100 R.first->second =
new NSSymbolMap();
101 return *R.first->second;
104 auto AddHeader = [&](llvm::StringRef
Header) ->
unsigned {
105 return Mapping->HeaderIDs->try_emplace(
Header, Mapping->HeaderIDs->size())
109 auto Add = [&, SymIndex(-1)](llvm::StringRef QName,
unsigned NSLen,
110 llvm::StringRef HeaderName)
mutable {
113 if (QName.take_front(NSLen) ==
"None") {
114 QName = QName.drop_front(NSLen);
119 assert(llvm::none_of(
llvm::ArrayRef(Mapping->SymbolNames, SymIndex),
120 [&QName](
const SymbolHeaderMapping::SymbolName &S) {
121 return S.qualifiedName() == QName;
123 "The symbol has been added before, make sure entries in the .inc "
124 "file are grouped by symbol name!");
127 Mapping->SymbolNames[SymIndex].qualifiedName() != QName) {
131 Mapping->SymbolNames[SymIndex] = {
132 QName.data(), NSLen,
static_cast<unsigned int>(QName.size() - NSLen)};
133 if (!HeaderName.empty())
134 Mapping->SymbolHeaderIDs[SymIndex].push_back(AddHeader(HeaderName));
136 NSSymbolMap &NSSymbols = AddNS(QName.take_front(NSLen));
137 NSSymbols.try_emplace(QName.drop_front(NSLen), SymIndex);
143 const char *HeaderName;
145#define SYMBOL(Name, NS, Header) \
146 {#NS #Name, static_cast<decltype(Symbol::NSLen)>(StringRef(#NS).size()), \
150 static constexpr Symbol CSymbols[] = {
154 for (
const Symbol &S : CSymbols)
155 Add(S.QName, S.NSLen, S.HeaderName);
159 static constexpr Symbol CXXSymbols[] = {
164 for (
const Symbol &S : CXXSymbols)
165 Add(S.QName, S.NSLen, S.HeaderName);
171 Mapping->HeaderNames =
new llvm::StringRef[Mapping->HeaderIDs->size()];
172 for (
const auto &
E : *Mapping->HeaderIDs)
173 Mapping->HeaderNames[
E.second] =
E.first;
179 static int Dummy = []() {
189 std::vector<Header>
Result;
191 Result.reserve(Mapping->HeaderIDs->size());
192 for (
unsigned I = 0,
E = Mapping->HeaderIDs->size(); I <
E; ++I)
199 auto It = Mapping->HeaderIDs->find(Name);
200 if (It == Mapping->HeaderIDs->end())
202 return Header(It->second, L);
210 std::vector<Symbol>
Result;
212 Result.reserve(Mapping->SymbolCount);
213 for (
unsigned I = 0,
E = Mapping->SymbolCount; I <
E; ++I)
230 if (NSSymbolMap *NSSymbols =
232 auto It = NSSymbols->find(Name);
233 if (It != NSSymbols->end())
234 return Symbol(It->second, L);
253NSSymbolMap *Recognizer::namespaceSymbols(
const DeclContext *DC,
Lang L) {
257 auto It = NamespaceCache.find(DC);
258 if (It != NamespaceCache.end())
261 NSSymbolMap *
Result = [&]() -> NSSymbolMap * {
262 if (
D->isAnonymousNamespace())
266 for (
const auto *ND =
D; ND;
267 ND = llvm::dyn_cast_or_null<NamespaceDecl>(ND->getParent()))
268 if (!ND->isInlineNamespace() && !ND->isAnonymousNamespace())
272 NamespaceCache.try_emplace(
D,
Result);
278 if (
D->getLangOpts().CPlusPlus)
280 else if (
D->getLangOpts().C99)
294 IntermediateDecl.push_back(DC);
297 NSSymbolMap *Symbols = namespaceSymbols(DC, L);
301 llvm::StringRef Name = [&]() -> llvm::StringRef {
302 for (
const auto *SymDC : llvm::reverse(IntermediateDecl)) {
305 return II->getName();
309 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(
D))
310 if (
const auto *II = ND->getIdentifier())
311 return II->getName();
317 auto It = Symbols->find(Name);
318 if (It == Symbols->end())
320 return Symbol(It->second, L);
Defines the clang::LangOptions interface.
llvm::DenseMap< llvm::StringRef, NSSymbolMap * > * NamespaceSymbols
llvm::StringRef * HeaderNames
struct clang::tooling::stdlib::@2046::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.
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.
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.