clang 22.0.0git
NestedNameSpecifier.h
Go to the documentation of this file.
1//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file completes the definition of the NestedNameSpecifier class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
14#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
15
16#include "clang/AST/Decl.h"
18#include "clang/AST/Type.h"
19#include "clang/AST/TypeLoc.h"
20#include "llvm/ADT/DenseMapInfo.h"
21
22namespace clang {
23
25 if (!isStoredKind()) {
26 switch (getFlagKind()) {
27 case FlagKind::Null:
28 return Kind::Null;
29 case FlagKind::Global:
30 return Kind::Global;
31 case FlagKind::Invalid:
32 llvm_unreachable("use of invalid NestedNameSpecifier");
33 }
34 llvm_unreachable("unhandled FlagKind");
35 }
36 switch (auto [K, Ptr] = getStored(); K) {
37 case StoredKind::Type:
38 return Kind::Type;
39 case StoredKind::NamespaceWithGlobal:
40 case StoredKind::NamespaceWithNamespace:
41 return Kind::Namespace;
42 case StoredKind::NamespaceOrSuper:
43 switch (static_cast<const Decl *>(Ptr)->getKind()) {
44 case Decl::Namespace:
45 case Decl::NamespaceAlias:
46 return Kind::Namespace;
47 case Decl::CXXRecord:
48 case Decl::ClassTemplateSpecialization:
49 case Decl::ClassTemplatePartialSpecialization:
51 default:
52 llvm_unreachable("unexpected decl kind");
53 }
54 }
55 llvm_unreachable("unknown StoredKind");
56}
57
59 : NestedNameSpecifier({StoredKind::Type, T}) {
60 assert(getKind() == Kind::Type);
61}
62
63auto NestedNameSpecifier::MakeNamespacePtrKind(
64 const ASTContext &Ctx, const NamespaceBaseDecl *Namespace,
65 NestedNameSpecifier Prefix) -> PtrKind {
66 switch (Prefix.getKind()) {
67 case Kind::Null:
68 return {StoredKind::NamespaceOrSuper, Namespace};
69 case Kind::Global:
70 return {StoredKind::NamespaceWithGlobal, Namespace};
71 case Kind::Namespace:
72 return {StoredKind::NamespaceWithNamespace,
73 MakeNamespaceAndPrefixStorage(Ctx, Namespace, Prefix)};
74 case Kind::MicrosoftSuper:
75 case Kind::Type:
76 llvm_unreachable("invalid prefix for namespace");
77 }
78 llvm_unreachable("unhandled kind");
79}
80
81/// Builds a nested name specifier that names a namespace.
83 const NamespaceBaseDecl *Namespace,
85 : NestedNameSpecifier(MakeNamespacePtrKind(Ctx, Namespace, Prefix)) {
86 assert(getKind() == Kind::Namespace);
87}
88
89/// Builds a nested name specifier that names a class through microsoft's
90/// __super specifier.
92 : NestedNameSpecifier({StoredKind::NamespaceOrSuper, RD}) {
93 assert(getKind() == Kind::MicrosoftSuper);
94}
95
97 switch (getKind()) {
99 return getAsMicrosoftSuper();
100 case Kind::Type:
101 return getAsType()->getAsCXXRecordDecl();
102 case Kind::Global:
103 case Kind::Namespace:
104 case Kind::Null:
105 return nullptr;
106 }
107 llvm_unreachable("Invalid NNS Kind!");
108}
109
111 switch (getKind()) {
115 // These are canonical and unique.
116 return *this;
118 // A namespace is canonical; build a nested-name-specifier with
119 // this namespace and no prefix.
121 return NestedNameSpecifier(
122 {StoredKind::NamespaceOrSuper, ND->getNamespace()->getCanonicalDecl()});
123 }
125 return NestedNameSpecifier(
126 getAsType()->getCanonicalTypeInternal().getTypePtr());
127 }
128 llvm_unreachable("unhandled kind");
129}
130
132 return *this == getCanonical();
133}
134
136 return TypeLoc(Qualifier.getAsType(), LoadPointer(/*Offset=*/0));
137}
138
140 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
141 return TypeLoc();
142 return castAsTypeLoc();
143}
144
145unsigned
146NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier Qualifier) {
147 // Location of the trailing '::'.
148 unsigned Length = sizeof(SourceLocation::UIntTy);
149
150 switch (Qualifier.getKind()) {
152 // Nothing more to add.
153 break;
154
157 // The location of the identifier or namespace name.
158 Length += sizeof(SourceLocation::UIntTy);
159 break;
160
162 // The "void*" that points at the TypeLoc data.
163 // Note: the 'template' keyword is part of the TypeLoc.
164 Length += sizeof(void *);
165 break;
166
168 llvm_unreachable("Expected a non-NULL qualifier");
169 }
170
171 return Length;
172}
173
175 auto [Namespace, Prefix] = Qualifier.getAsNamespaceAndPrefix();
176 return {Namespace, NestedNameSpecifierLoc(Prefix, Data)};
177}
178
180 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Namespace)
181 return {};
183}
184
186 unsigned Length = 0;
187 for (; Qualifier; Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix) {
188 Length += getLocalDataLength(Qualifier);
189 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Namespace)
190 break;
191 }
192 return Length;
193}
194
196 return getDataLength(Qualifier);
197}
198
200 switch (auto Kind = Qualifier.getKind()) {
202 return SourceRange();
204 return LoadSourceLocation(/*Offset=*/0);
207 unsigned Offset =
209 ? getDataLength(Qualifier.getAsNamespaceAndPrefix().Prefix)
210 : 0;
211 return SourceRange(
212 LoadSourceLocation(Offset),
213 LoadSourceLocation(Offset + sizeof(SourceLocation::UIntTy)));
214 }
216 // The "void*" that points at the TypeLoc data.
217 // Note: the 'template' keyword is part of the TypeLoc.
218 void *TypeData = LoadPointer(/*Offset=*/0);
219 TypeLoc TL(Qualifier.getAsType(), TypeData);
220 return SourceRange(TL.getBeginLoc(), LoadSourceLocation(sizeof(void *)));
221 }
222 }
223
224 llvm_unreachable("Invalid NNS Kind!");
225}
226
228 return SourceRange(getBeginLoc(), getEndLoc());
229}
230
232 return getLocalSourceRange().getEnd();
233}
234
235/// Retrieve the location of the beginning of this
236/// component of the nested-name-specifier.
238 return getLocalSourceRange().getBegin();
239}
240
241/// Retrieve the location of the end of this component of the
242/// nested-name-specifier.
244 return getLocalSourceRange().getEnd();
245}
246
248 return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
249}
250
251} // namespace clang
252
253namespace llvm {
254
255template <> struct DenseMapInfo<clang::NestedNameSpecifier> {
256 static clang::NestedNameSpecifier getEmptyKey() { return std::nullopt; }
257
260 }
261
262 static unsigned getHashValue(const clang::NestedNameSpecifier &V) {
263 return hash_combine(V.getAsVoidPointer());
264 }
265};
266
267template <> struct DenseMapInfo<clang::NestedNameSpecifierLoc> {
268 using FirstInfo = DenseMapInfo<clang::NestedNameSpecifier>;
269 using SecondInfo = DenseMapInfo<void *>;
270
272 return clang::NestedNameSpecifierLoc(FirstInfo::getEmptyKey(),
273 SecondInfo::getEmptyKey());
274 }
275
277 return clang::NestedNameSpecifierLoc(FirstInfo::getTombstoneKey(),
278 SecondInfo::getTombstoneKey());
279 }
280
281 static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal) {
282 return hash_combine(
283 FirstInfo::getHashValue(PairVal.getNestedNameSpecifier()),
284 SecondInfo::getHashValue(PairVal.getOpaqueData()));
285 }
286
289 return LHS == RHS;
290 }
291};
292} // namespace llvm
293
294#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define V(N, I)
Definition: ASTContext.h:3597
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1192
static const Decl * getCanonicalDecl(const Decl *D)
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Represents C++ namespaces and their aliases.
Definition: Decl.h:572
NamespaceDecl * getNamespace()
Definition: DeclCXX.cpp:3222
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covered by this nested-name-specifier.
A C++ nested-name-specifier augmented with source location information.
NamespaceAndPrefixLoc getAsNamespaceAndPrefix() const
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
SourceLocation getLocalEndLoc() const
Retrieve the location of the end of this component of the nested-name-specifier.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
NestedNameSpecifierLoc()=default
Construct an empty nested-name-specifier.
NamespaceAndPrefixLoc castAsNamespaceAndPrefix() const
For a nested-name-specifier that refers to a namespace, retrieve the namespace and its prefix.
SourceLocation getEndLoc() const
Retrieve the location of the end of this nested-name-specifier.
SourceLocation getBeginLoc() const
Retrieve the location of the beginning of this nested-name-specifier.
TypeLoc castAsTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
SourceRange getLocalSourceRange() const
Retrieve the source range covering just the last part of this nested-name-specifier,...
SourceLocation getLocalBeginLoc() const
Retrieve the location of the beginning of this component of the nested-name-specifier.
unsigned getDataLength() const
Determines the data length for the entire nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NestedNameSpecifier getCanonical() const
Retrieves the "canonical" nested name specifier for a given nested name specifier.
CXXRecordDecl * getAsMicrosoftSuper() const
NamespaceAndPrefix getAsNamespaceAndPrefix() const
bool isCanonical() const
Whether this nested name specifier is canonical.
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier, or null.
static constexpr NestedNameSpecifier getInvalid()
Kind
The kind of specifier that completes this nested name specifier.
@ MicrosoftSuper
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Global
The global specifier '::'. There is no stored value.
@ Type
A type, stored as a Type*.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:193
The base class of the type hierarchy.
Definition: TypeBase.h:1833
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.h:26
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
const NamespaceBaseDecl * Namespace
static bool isEqual(const clang::NestedNameSpecifierLoc &LHS, const clang::NestedNameSpecifierLoc &RHS)
static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal)
static clang::NestedNameSpecifierLoc getEmptyKey()
static clang::NestedNameSpecifierLoc getTombstoneKey()
static clang::NestedNameSpecifier getEmptyKey()
static unsigned getHashValue(const clang::NestedNameSpecifier &V)
static clang::NestedNameSpecifier getTombstoneKey()