Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- TemplateName.h - C++ Template Name Representation --------*- 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 defines the TemplateName interface and subclasses. |
||
| 10 | // |
||
| 11 | //===----------------------------------------------------------------------===// |
||
| 12 | |||
| 13 | #ifndef LLVM_CLANG_AST_TEMPLATENAME_H |
||
| 14 | #define LLVM_CLANG_AST_TEMPLATENAME_H |
||
| 15 | |||
| 16 | #include "clang/AST/DependenceFlags.h" |
||
| 17 | #include "clang/AST/NestedNameSpecifier.h" |
||
| 18 | #include "clang/Basic/LLVM.h" |
||
| 19 | #include "llvm/ADT/FoldingSet.h" |
||
| 20 | #include "llvm/ADT/PointerIntPair.h" |
||
| 21 | #include "llvm/ADT/PointerUnion.h" |
||
| 22 | #include "llvm/Support/PointerLikeTypeTraits.h" |
||
| 23 | #include <cassert> |
||
| 24 | #include <optional> |
||
| 25 | |||
| 26 | namespace clang { |
||
| 27 | |||
| 28 | class ASTContext; |
||
| 29 | class Decl; |
||
| 30 | class DependentTemplateName; |
||
| 31 | class IdentifierInfo; |
||
| 32 | class NamedDecl; |
||
| 33 | class NestedNameSpecifier; |
||
| 34 | enum OverloadedOperatorKind : int; |
||
| 35 | class OverloadedTemplateStorage; |
||
| 36 | class AssumedTemplateStorage; |
||
| 37 | struct PrintingPolicy; |
||
| 38 | class QualifiedTemplateName; |
||
| 39 | class SubstTemplateTemplateParmPackStorage; |
||
| 40 | class SubstTemplateTemplateParmStorage; |
||
| 41 | class TemplateArgument; |
||
| 42 | class TemplateDecl; |
||
| 43 | class TemplateTemplateParmDecl; |
||
| 44 | class UsingShadowDecl; |
||
| 45 | |||
| 46 | /// Implementation class used to describe either a set of overloaded |
||
| 47 | /// template names or an already-substituted template template parameter pack. |
||
| 48 | class UncommonTemplateNameStorage { |
||
| 49 | protected: |
||
| 50 | enum Kind { |
||
| 51 | Overloaded, |
||
| 52 | Assumed, // defined in DeclarationName.h |
||
| 53 | SubstTemplateTemplateParm, |
||
| 54 | SubstTemplateTemplateParmPack |
||
| 55 | }; |
||
| 56 | |||
| 57 | struct BitsTag { |
||
| 58 | /// A Kind. |
||
| 59 | unsigned Kind : 2; |
||
| 60 | |||
| 61 | // The template parameter index. |
||
| 62 | unsigned Index : 15; |
||
| 63 | |||
| 64 | /// The pack index, or the number of stored templates |
||
| 65 | /// or template arguments, depending on which subclass we have. |
||
| 66 | unsigned Data : 15; |
||
| 67 | }; |
||
| 68 | |||
| 69 | union { |
||
| 70 | struct BitsTag Bits; |
||
| 71 | void *PointerAlignment; |
||
| 72 | }; |
||
| 73 | |||
| 74 | UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data) { |
||
| 75 | Bits.Kind = Kind; |
||
| 76 | Bits.Index = Index; |
||
| 77 | Bits.Data = Data; |
||
| 78 | } |
||
| 79 | |||
| 80 | public: |
||
| 81 | OverloadedTemplateStorage *getAsOverloadedStorage() { |
||
| 82 | return Bits.Kind == Overloaded |
||
| 83 | ? reinterpret_cast<OverloadedTemplateStorage *>(this) |
||
| 84 | : nullptr; |
||
| 85 | } |
||
| 86 | |||
| 87 | AssumedTemplateStorage *getAsAssumedTemplateName() { |
||
| 88 | return Bits.Kind == Assumed |
||
| 89 | ? reinterpret_cast<AssumedTemplateStorage *>(this) |
||
| 90 | : nullptr; |
||
| 91 | } |
||
| 92 | |||
| 93 | SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() { |
||
| 94 | return Bits.Kind == SubstTemplateTemplateParm |
||
| 95 | ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this) |
||
| 96 | : nullptr; |
||
| 97 | } |
||
| 98 | |||
| 99 | SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() { |
||
| 100 | return Bits.Kind == SubstTemplateTemplateParmPack |
||
| 101 | ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) |
||
| 102 | : nullptr; |
||
| 103 | } |
||
| 104 | }; |
||
| 105 | |||
| 106 | /// A structure for storing the information associated with an |
||
| 107 | /// overloaded template name. |
||
| 108 | class OverloadedTemplateStorage : public UncommonTemplateNameStorage { |
||
| 109 | friend class ASTContext; |
||
| 110 | |||
| 111 | OverloadedTemplateStorage(unsigned size) |
||
| 112 | : UncommonTemplateNameStorage(Overloaded, 0, size) {} |
||
| 113 | |||
| 114 | NamedDecl **getStorage() { |
||
| 115 | return reinterpret_cast<NamedDecl **>(this + 1); |
||
| 116 | } |
||
| 117 | NamedDecl * const *getStorage() const { |
||
| 118 | return reinterpret_cast<NamedDecl *const *>(this + 1); |
||
| 119 | } |
||
| 120 | |||
| 121 | public: |
||
| 122 | unsigned size() const { return Bits.Data; } |
||
| 123 | |||
| 124 | using iterator = NamedDecl *const *; |
||
| 125 | |||
| 126 | iterator begin() const { return getStorage(); } |
||
| 127 | iterator end() const { return getStorage() + Bits.Data; } |
||
| 128 | |||
| 129 | llvm::ArrayRef<NamedDecl*> decls() const { |
||
| 130 | return llvm::ArrayRef(begin(), end()); |
||
| 131 | } |
||
| 132 | }; |
||
| 133 | |||
| 134 | /// A structure for storing an already-substituted template template |
||
| 135 | /// parameter pack. |
||
| 136 | /// |
||
| 137 | /// This kind of template names occurs when the parameter pack has been |
||
| 138 | /// provided with a template template argument pack in a context where its |
||
| 139 | /// enclosing pack expansion could not be fully expanded. |
||
| 140 | class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage, |
||
| 141 | public llvm::FoldingSetNode { |
||
| 142 | const TemplateArgument *Arguments; |
||
| 143 | llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; |
||
| 144 | |||
| 145 | public: |
||
| 146 | SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack, |
||
| 147 | Decl *AssociatedDecl, unsigned Index, |
||
| 148 | bool Final); |
||
| 149 | |||
| 150 | /// A template-like entity which owns the whole pattern being substituted. |
||
| 151 | /// This will own a set of template parameters. |
||
| 152 | Decl *getAssociatedDecl() const; |
||
| 153 | |||
| 154 | /// Returns the index of the replaced parameter in the associated declaration. |
||
| 155 | /// This should match the result of `getParameterPack()->getIndex()`. |
||
| 156 | unsigned getIndex() const { return Bits.Index; } |
||
| 157 | |||
| 158 | // When true the substitution will be 'Final' (subst node won't be placed). |
||
| 159 | bool getFinal() const; |
||
| 160 | |||
| 161 | /// Retrieve the template template parameter pack being substituted. |
||
| 162 | TemplateTemplateParmDecl *getParameterPack() const; |
||
| 163 | |||
| 164 | /// Retrieve the template template argument pack with which this |
||
| 165 | /// parameter was substituted. |
||
| 166 | TemplateArgument getArgumentPack() const; |
||
| 167 | |||
| 168 | void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context); |
||
| 169 | |||
| 170 | static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, |
||
| 171 | const TemplateArgument &ArgPack, Decl *AssociatedDecl, |
||
| 172 | unsigned Index, bool Final); |
||
| 173 | }; |
||
| 174 | |||
| 175 | /// Represents a C++ template name within the type system. |
||
| 176 | /// |
||
| 177 | /// A C++ template name refers to a template within the C++ type |
||
| 178 | /// system. In most cases, a template name is simply a reference to a |
||
| 179 | /// class template, e.g. |
||
| 180 | /// |
||
| 181 | /// \code |
||
| 182 | /// template<typename T> class X { }; |
||
| 183 | /// |
||
| 184 | /// X<int> xi; |
||
| 185 | /// \endcode |
||
| 186 | /// |
||
| 187 | /// Here, the 'X' in \c X<int> is a template name that refers to the |
||
| 188 | /// declaration of the class template X, above. Template names can |
||
| 189 | /// also refer to function templates, C++0x template aliases, etc. |
||
| 190 | /// |
||
| 191 | /// Some template names are dependent. For example, consider: |
||
| 192 | /// |
||
| 193 | /// \code |
||
| 194 | /// template<typename MetaFun, typename T1, typename T2> struct apply2 { |
||
| 195 | /// typedef typename MetaFun::template apply<T1, T2>::type type; |
||
| 196 | /// }; |
||
| 197 | /// \endcode |
||
| 198 | /// |
||
| 199 | /// Here, "apply" is treated as a template name within the typename |
||
| 200 | /// specifier in the typedef. "apply" is a nested template, and can |
||
| 201 | /// only be understood in the context of |
||
| 202 | class TemplateName { |
||
| 203 | // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the |
||
| 204 | // NameKind. |
||
| 205 | // !! There is no free low bits in 32-bit builds to discriminate more than 4 |
||
| 206 | // pointer types in PointerUnion. |
||
| 207 | using StorageType = |
||
| 208 | llvm::PointerUnion<Decl *, UncommonTemplateNameStorage *, |
||
| 209 | QualifiedTemplateName *, DependentTemplateName *>; |
||
| 210 | |||
| 211 | StorageType Storage; |
||
| 212 | |||
| 213 | explicit TemplateName(void *Ptr); |
||
| 214 | |||
| 215 | public: |
||
| 216 | // Kind of name that is actually stored. |
||
| 217 | enum NameKind { |
||
| 218 | /// A single template declaration. |
||
| 219 | Template, |
||
| 220 | |||
| 221 | /// A set of overloaded template declarations. |
||
| 222 | OverloadedTemplate, |
||
| 223 | |||
| 224 | /// An unqualified-id that has been assumed to name a function template |
||
| 225 | /// that will be found by ADL. |
||
| 226 | AssumedTemplate, |
||
| 227 | |||
| 228 | /// A qualified template name, where the qualification is kept |
||
| 229 | /// to describe the source code as written. |
||
| 230 | QualifiedTemplate, |
||
| 231 | |||
| 232 | /// A dependent template name that has not been resolved to a |
||
| 233 | /// template (or set of templates). |
||
| 234 | DependentTemplate, |
||
| 235 | |||
| 236 | /// A template template parameter that has been substituted |
||
| 237 | /// for some other template name. |
||
| 238 | SubstTemplateTemplateParm, |
||
| 239 | |||
| 240 | /// A template template parameter pack that has been substituted for |
||
| 241 | /// a template template argument pack, but has not yet been expanded into |
||
| 242 | /// individual arguments. |
||
| 243 | SubstTemplateTemplateParmPack, |
||
| 244 | |||
| 245 | /// A template name that refers to a template declaration found through a |
||
| 246 | /// specific using shadow declaration. |
||
| 247 | UsingTemplate, |
||
| 248 | }; |
||
| 249 | |||
| 250 | TemplateName() = default; |
||
| 251 | explicit TemplateName(TemplateDecl *Template); |
||
| 252 | explicit TemplateName(OverloadedTemplateStorage *Storage); |
||
| 253 | explicit TemplateName(AssumedTemplateStorage *Storage); |
||
| 254 | explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); |
||
| 255 | explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage); |
||
| 256 | explicit TemplateName(QualifiedTemplateName *Qual); |
||
| 257 | explicit TemplateName(DependentTemplateName *Dep); |
||
| 258 | explicit TemplateName(UsingShadowDecl *Using); |
||
| 259 | |||
| 260 | /// Determine whether this template name is NULL. |
||
| 261 | bool isNull() const; |
||
| 262 | |||
| 263 | // Get the kind of name that is actually stored. |
||
| 264 | NameKind getKind() const; |
||
| 265 | |||
| 266 | /// Retrieve the underlying template declaration that |
||
| 267 | /// this template name refers to, if known. |
||
| 268 | /// |
||
| 269 | /// \returns The template declaration that this template name refers |
||
| 270 | /// to, if any. If the template name does not refer to a specific |
||
| 271 | /// declaration because it is a dependent name, or if it refers to a |
||
| 272 | /// set of function templates, returns NULL. |
||
| 273 | TemplateDecl *getAsTemplateDecl() const; |
||
| 274 | |||
| 275 | /// Retrieve the underlying, overloaded function template |
||
| 276 | /// declarations that this template name refers to, if known. |
||
| 277 | /// |
||
| 278 | /// \returns The set of overloaded function templates that this template |
||
| 279 | /// name refers to, if known. If the template name does not refer to a |
||
| 280 | /// specific set of function templates because it is a dependent name or |
||
| 281 | /// refers to a single template, returns NULL. |
||
| 282 | OverloadedTemplateStorage *getAsOverloadedTemplate() const; |
||
| 283 | |||
| 284 | /// Retrieve information on a name that has been assumed to be a |
||
| 285 | /// template-name in order to permit a call via ADL. |
||
| 286 | AssumedTemplateStorage *getAsAssumedTemplateName() const; |
||
| 287 | |||
| 288 | /// Retrieve the substituted template template parameter, if |
||
| 289 | /// known. |
||
| 290 | /// |
||
| 291 | /// \returns The storage for the substituted template template parameter, |
||
| 292 | /// if known. Otherwise, returns NULL. |
||
| 293 | SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const; |
||
| 294 | |||
| 295 | /// Retrieve the substituted template template parameter pack, if |
||
| 296 | /// known. |
||
| 297 | /// |
||
| 298 | /// \returns The storage for the substituted template template parameter pack, |
||
| 299 | /// if known. Otherwise, returns NULL. |
||
| 300 | SubstTemplateTemplateParmPackStorage * |
||
| 301 | getAsSubstTemplateTemplateParmPack() const; |
||
| 302 | |||
| 303 | /// Retrieve the underlying qualified template name |
||
| 304 | /// structure, if any. |
||
| 305 | QualifiedTemplateName *getAsQualifiedTemplateName() const; |
||
| 306 | |||
| 307 | /// Retrieve the underlying dependent template name |
||
| 308 | /// structure, if any. |
||
| 309 | DependentTemplateName *getAsDependentTemplateName() const; |
||
| 310 | |||
| 311 | /// Retrieve the using shadow declaration through which the underlying |
||
| 312 | /// template declaration is introduced, if any. |
||
| 313 | UsingShadowDecl *getAsUsingShadowDecl() const; |
||
| 314 | |||
| 315 | TemplateName getUnderlying() const; |
||
| 316 | |||
| 317 | /// Get the template name to substitute when this template name is used as a |
||
| 318 | /// template template argument. This refers to the most recent declaration of |
||
| 319 | /// the template, including any default template arguments. |
||
| 320 | TemplateName getNameToSubstitute() const; |
||
| 321 | |||
| 322 | TemplateNameDependence getDependence() const; |
||
| 323 | |||
| 324 | /// Determines whether this is a dependent template name. |
||
| 325 | bool isDependent() const; |
||
| 326 | |||
| 327 | /// Determines whether this is a template name that somehow |
||
| 328 | /// depends on a template parameter. |
||
| 329 | bool isInstantiationDependent() const; |
||
| 330 | |||
| 331 | /// Determines whether this template name contains an |
||
| 332 | /// unexpanded parameter pack (for C++0x variadic templates). |
||
| 333 | bool containsUnexpandedParameterPack() const; |
||
| 334 | |||
| 335 | enum class Qualified { None, AsWritten, Fully }; |
||
| 336 | /// Print the template name. |
||
| 337 | /// |
||
| 338 | /// \param OS the output stream to which the template name will be |
||
| 339 | /// printed. |
||
| 340 | /// |
||
| 341 | /// \param Qual print the (Qualified::None) simple name, |
||
| 342 | /// (Qualified::AsWritten) any written (possibly partial) qualifier, or |
||
| 343 | /// (Qualified::Fully) the fully qualified name. |
||
| 344 | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
||
| 345 | Qualified Qual = Qualified::AsWritten) const; |
||
| 346 | |||
| 347 | /// Debugging aid that dumps the template name. |
||
| 348 | void dump(raw_ostream &OS) const; |
||
| 349 | |||
| 350 | /// Debugging aid that dumps the template name to standard |
||
| 351 | /// error. |
||
| 352 | void dump() const; |
||
| 353 | |||
| 354 | void Profile(llvm::FoldingSetNodeID &ID) { |
||
| 355 | ID.AddPointer(Storage.getOpaqueValue()); |
||
| 356 | } |
||
| 357 | |||
| 358 | /// Retrieve the template name as a void pointer. |
||
| 359 | void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } |
||
| 360 | |||
| 361 | /// Build a template name from a void pointer. |
||
| 362 | static TemplateName getFromVoidPointer(void *Ptr) { |
||
| 363 | return TemplateName(Ptr); |
||
| 364 | } |
||
| 365 | }; |
||
| 366 | |||
| 367 | /// Insertion operator for diagnostics. This allows sending TemplateName's |
||
| 368 | /// into a diagnostic with <<. |
||
| 369 | const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, |
||
| 370 | TemplateName N); |
||
| 371 | |||
| 372 | /// A structure for storing the information associated with a |
||
| 373 | /// substituted template template parameter. |
||
| 374 | class SubstTemplateTemplateParmStorage |
||
| 375 | : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { |
||
| 376 | friend class ASTContext; |
||
| 377 | |||
| 378 | TemplateName Replacement; |
||
| 379 | Decl *AssociatedDecl; |
||
| 380 | |||
| 381 | SubstTemplateTemplateParmStorage(TemplateName Replacement, |
||
| 382 | Decl *AssociatedDecl, unsigned Index, |
||
| 383 | std::optional<unsigned> PackIndex) |
||
| 384 | : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index, |
||
| 385 | PackIndex ? *PackIndex + 1 : 0), |
||
| 386 | Replacement(Replacement), AssociatedDecl(AssociatedDecl) { |
||
| 387 | assert(AssociatedDecl != nullptr); |
||
| 388 | } |
||
| 389 | |||
| 390 | public: |
||
| 391 | /// A template-like entity which owns the whole pattern being substituted. |
||
| 392 | /// This will own a set of template parameters. |
||
| 393 | Decl *getAssociatedDecl() const { return AssociatedDecl; } |
||
| 394 | |||
| 395 | /// Returns the index of the replaced parameter in the associated declaration. |
||
| 396 | /// This should match the result of `getParameter()->getIndex()`. |
||
| 397 | unsigned getIndex() const { return Bits.Index; } |
||
| 398 | |||
| 399 | std::optional<unsigned> getPackIndex() const { |
||
| 400 | if (Bits.Data == 0) |
||
| 401 | return std::nullopt; |
||
| 402 | return Bits.Data - 1; |
||
| 403 | } |
||
| 404 | |||
| 405 | TemplateTemplateParmDecl *getParameter() const; |
||
| 406 | TemplateName getReplacement() const { return Replacement; } |
||
| 407 | |||
| 408 | void Profile(llvm::FoldingSetNodeID &ID); |
||
| 409 | |||
| 410 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement, |
||
| 411 | Decl *AssociatedDecl, unsigned Index, |
||
| 412 | std::optional<unsigned> PackIndex); |
||
| 413 | }; |
||
| 414 | |||
| 415 | inline TemplateName TemplateName::getUnderlying() const { |
||
| 416 | if (SubstTemplateTemplateParmStorage *subst |
||
| 417 | = getAsSubstTemplateTemplateParm()) |
||
| 418 | return subst->getReplacement().getUnderlying(); |
||
| 419 | return *this; |
||
| 420 | } |
||
| 421 | |||
| 422 | /// Represents a template name that was expressed as a |
||
| 423 | /// qualified name. |
||
| 424 | /// |
||
| 425 | /// This kind of template name refers to a template name that was |
||
| 426 | /// preceded by a nested name specifier, e.g., \c std::vector. Here, |
||
| 427 | /// the nested name specifier is "std::" and the template name is the |
||
| 428 | /// declaration for "vector". The QualifiedTemplateName class is only |
||
| 429 | /// used to provide "sugar" for template names that were expressed |
||
| 430 | /// with a qualified name, and has no semantic meaning. In this |
||
| 431 | /// manner, it is to TemplateName what ElaboratedType is to Type, |
||
| 432 | /// providing extra syntactic sugar for downstream clients. |
||
| 433 | class QualifiedTemplateName : public llvm::FoldingSetNode { |
||
| 434 | friend class ASTContext; |
||
| 435 | |||
| 436 | /// The nested name specifier that qualifies the template name. |
||
| 437 | /// |
||
| 438 | /// The bit is used to indicate whether the "template" keyword was |
||
| 439 | /// present before the template name itself. Note that the |
||
| 440 | /// "template" keyword is always redundant in this case (otherwise, |
||
| 441 | /// the template name would be a dependent name and we would express |
||
| 442 | /// this name with DependentTemplateName). |
||
| 443 | llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier; |
||
| 444 | |||
| 445 | /// The underlying template name, it is either |
||
| 446 | /// 1) a Template -- a template declaration that this qualified name refers |
||
| 447 | /// to. |
||
| 448 | /// 2) or a UsingTemplate -- a template declaration introduced by a |
||
| 449 | /// using-shadow declaration. |
||
| 450 | TemplateName UnderlyingTemplate; |
||
| 451 | |||
| 452 | QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, |
||
| 453 | TemplateName Template) |
||
| 454 | : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) { |
||
| 455 | assert(UnderlyingTemplate.getKind() == TemplateName::Template || |
||
| 456 | UnderlyingTemplate.getKind() == TemplateName::UsingTemplate); |
||
| 457 | } |
||
| 458 | |||
| 459 | public: |
||
| 460 | /// Return the nested name specifier that qualifies this name. |
||
| 461 | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
||
| 462 | |||
| 463 | /// Whether the template name was prefixed by the "template" |
||
| 464 | /// keyword. |
||
| 465 | bool hasTemplateKeyword() const { return Qualifier.getInt(); } |
||
| 466 | |||
| 467 | /// Return the underlying template name. |
||
| 468 | TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; } |
||
| 469 | |||
| 470 | void Profile(llvm::FoldingSetNodeID &ID) { |
||
| 471 | Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate); |
||
| 472 | } |
||
| 473 | |||
| 474 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
||
| 475 | bool TemplateKeyword, TemplateName TN) { |
||
| 476 | ID.AddPointer(NNS); |
||
| 477 | ID.AddBoolean(TemplateKeyword); |
||
| 478 | ID.AddPointer(TN.getAsVoidPointer()); |
||
| 479 | } |
||
| 480 | }; |
||
| 481 | |||
| 482 | /// Represents a dependent template name that cannot be |
||
| 483 | /// resolved prior to template instantiation. |
||
| 484 | /// |
||
| 485 | /// This kind of template name refers to a dependent template name, |
||
| 486 | /// including its nested name specifier (if any). For example, |
||
| 487 | /// DependentTemplateName can refer to "MetaFun::template apply", |
||
| 488 | /// where "MetaFun::" is the nested name specifier and "apply" is the |
||
| 489 | /// template name referenced. The "template" keyword is implied. |
||
| 490 | class DependentTemplateName : public llvm::FoldingSetNode { |
||
| 491 | friend class ASTContext; |
||
| 492 | |||
| 493 | /// The nested name specifier that qualifies the template |
||
| 494 | /// name. |
||
| 495 | /// |
||
| 496 | /// The bit stored in this qualifier describes whether the \c Name field |
||
| 497 | /// is interpreted as an IdentifierInfo pointer (when clear) or as an |
||
| 498 | /// overloaded operator kind (when set). |
||
| 499 | llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier; |
||
| 500 | |||
| 501 | /// The dependent template name. |
||
| 502 | union { |
||
| 503 | /// The identifier template name. |
||
| 504 | /// |
||
| 505 | /// Only valid when the bit on \c Qualifier is clear. |
||
| 506 | const IdentifierInfo *Identifier; |
||
| 507 | |||
| 508 | /// The overloaded operator name. |
||
| 509 | /// |
||
| 510 | /// Only valid when the bit on \c Qualifier is set. |
||
| 511 | OverloadedOperatorKind Operator; |
||
| 512 | }; |
||
| 513 | |||
| 514 | /// The canonical template name to which this dependent |
||
| 515 | /// template name refers. |
||
| 516 | /// |
||
| 517 | /// The canonical template name for a dependent template name is |
||
| 518 | /// another dependent template name whose nested name specifier is |
||
| 519 | /// canonical. |
||
| 520 | TemplateName CanonicalTemplateName; |
||
| 521 | |||
| 522 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
| 523 | const IdentifierInfo *Identifier) |
||
| 524 | : Qualifier(Qualifier, false), Identifier(Identifier), |
||
| 525 | CanonicalTemplateName(this) {} |
||
| 526 | |||
| 527 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
| 528 | const IdentifierInfo *Identifier, |
||
| 529 | TemplateName Canon) |
||
| 530 | : Qualifier(Qualifier, false), Identifier(Identifier), |
||
| 531 | CanonicalTemplateName(Canon) {} |
||
| 532 | |||
| 533 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
| 534 | OverloadedOperatorKind Operator) |
||
| 535 | : Qualifier(Qualifier, true), Operator(Operator), |
||
| 536 | CanonicalTemplateName(this) {} |
||
| 537 | |||
| 538 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
| 539 | OverloadedOperatorKind Operator, |
||
| 540 | TemplateName Canon) |
||
| 541 | : Qualifier(Qualifier, true), Operator(Operator), |
||
| 542 | CanonicalTemplateName(Canon) {} |
||
| 543 | |||
| 544 | public: |
||
| 545 | /// Return the nested name specifier that qualifies this name. |
||
| 546 | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
||
| 547 | |||
| 548 | /// Determine whether this template name refers to an identifier. |
||
| 549 | bool isIdentifier() const { return !Qualifier.getInt(); } |
||
| 550 | |||
| 551 | /// Returns the identifier to which this template name refers. |
||
| 552 | const IdentifierInfo *getIdentifier() const { |
||
| 553 | assert(isIdentifier() && "Template name isn't an identifier?"); |
||
| 554 | return Identifier; |
||
| 555 | } |
||
| 556 | |||
| 557 | /// Determine whether this template name refers to an overloaded |
||
| 558 | /// operator. |
||
| 559 | bool isOverloadedOperator() const { return Qualifier.getInt(); } |
||
| 560 | |||
| 561 | /// Return the overloaded operator to which this template name refers. |
||
| 562 | OverloadedOperatorKind getOperator() const { |
||
| 563 | assert(isOverloadedOperator() && |
||
| 564 | "Template name isn't an overloaded operator?"); |
||
| 565 | return Operator; |
||
| 566 | } |
||
| 567 | |||
| 568 | void Profile(llvm::FoldingSetNodeID &ID) { |
||
| 569 | if (isIdentifier()) |
||
| 570 | Profile(ID, getQualifier(), getIdentifier()); |
||
| 571 | else |
||
| 572 | Profile(ID, getQualifier(), getOperator()); |
||
| 573 | } |
||
| 574 | |||
| 575 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
||
| 576 | const IdentifierInfo *Identifier) { |
||
| 577 | ID.AddPointer(NNS); |
||
| 578 | ID.AddBoolean(false); |
||
| 579 | ID.AddPointer(Identifier); |
||
| 580 | } |
||
| 581 | |||
| 582 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
||
| 583 | OverloadedOperatorKind Operator) { |
||
| 584 | ID.AddPointer(NNS); |
||
| 585 | ID.AddBoolean(true); |
||
| 586 | ID.AddInteger(Operator); |
||
| 587 | } |
||
| 588 | }; |
||
| 589 | |||
| 590 | } // namespace clang. |
||
| 591 | |||
| 592 | namespace llvm { |
||
| 593 | |||
| 594 | /// The clang::TemplateName class is effectively a pointer. |
||
| 595 | template<> |
||
| 596 | struct PointerLikeTypeTraits<clang::TemplateName> { |
||
| 597 | static inline void *getAsVoidPointer(clang::TemplateName TN) { |
||
| 598 | return TN.getAsVoidPointer(); |
||
| 599 | } |
||
| 600 | |||
| 601 | static inline clang::TemplateName getFromVoidPointer(void *Ptr) { |
||
| 602 | return clang::TemplateName::getFromVoidPointer(Ptr); |
||
| 603 | } |
||
| 604 | |||
| 605 | // No bits are available! |
||
| 606 | static constexpr int NumLowBitsAvailable = 0; |
||
| 607 | }; |
||
| 608 | |||
| 609 | } // namespace llvm. |
||
| 610 | |||
| 611 | #endif // LLVM_CLANG_AST_TEMPLATENAME_H |