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 |