TemplateName.h revision 208954
1//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the TemplateName interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_TEMPLATENAME_H 15#define LLVM_CLANG_AST_TEMPLATENAME_H 16 17#include "llvm/ADT/FoldingSet.h" 18#include "llvm/ADT/PointerUnion.h" 19#include "clang/Basic/OperatorKinds.h" 20 21namespace llvm { 22 class raw_ostream; 23} 24 25namespace clang { 26 27class DependentTemplateName; 28class DiagnosticBuilder; 29class IdentifierInfo; 30class NestedNameSpecifier; 31struct PrintingPolicy; 32class QualifiedTemplateName; 33class NamedDecl; 34class TemplateDecl; 35 36/// \brief A structure for storing the information associated with an 37/// overloaded template name. 38class OverloadedTemplateStorage { 39 union { 40 unsigned Size; 41 NamedDecl *Storage[1]; 42 }; 43 44 friend class ASTContext; 45 46 OverloadedTemplateStorage(unsigned Size) : Size(Size) {} 47 48 NamedDecl **getStorage() { 49 return &Storage[1]; 50 } 51 NamedDecl * const *getStorage() const { 52 return &Storage[1]; 53 } 54 55public: 56 typedef NamedDecl *const *iterator; 57 58 unsigned size() const { return Size; } 59 60 iterator begin() const { return getStorage(); } 61 iterator end() const { return getStorage() + size(); } 62}; 63 64/// \brief Represents a C++ template name within the type system. 65/// 66/// A C++ template name refers to a template within the C++ type 67/// system. In most cases, a template name is simply a reference to a 68/// class template, e.g. 69/// 70/// \code 71/// template<typename T> class X { }; 72/// 73/// X<int> xi; 74/// \endcode 75/// 76/// Here, the 'X' in \c X<int> is a template name that refers to the 77/// declaration of the class template X, above. Template names can 78/// also refer to function templates, C++0x template aliases, etc. 79/// 80/// Some template names are dependent. For example, consider: 81/// 82/// \code 83/// template<typename MetaFun, typename T1, typename T2> struct apply2 { 84/// typedef typename MetaFun::template apply<T1, T2>::type type; 85/// }; 86/// \endcode 87/// 88/// Here, "apply" is treated as a template name within the typename 89/// specifier in the typedef. "apply" is a nested template, and can 90/// only be understood in the context of 91class TemplateName { 92 typedef llvm::PointerUnion4<TemplateDecl *, 93 OverloadedTemplateStorage *, 94 QualifiedTemplateName *, 95 DependentTemplateName *> StorageType; 96 97 StorageType Storage; 98 99 explicit TemplateName(void *Ptr) { 100 Storage = StorageType::getFromOpaqueValue(Ptr); 101 } 102 103public: 104 TemplateName() : Storage() { } 105 explicit TemplateName(TemplateDecl *Template) : Storage(Template) { } 106 explicit TemplateName(OverloadedTemplateStorage *Storage) 107 : Storage(Storage) { } 108 explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { } 109 explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { } 110 111 /// \brief Determine whether this template name is NULL. 112 bool isNull() const { return Storage.isNull(); } 113 114 /// \brief Retrieve the the underlying template declaration that 115 /// this template name refers to, if known. 116 /// 117 /// \returns The template declaration that this template name refers 118 /// to, if any. If the template name does not refer to a specific 119 /// declaration because it is a dependent name, or if it refers to a 120 /// set of function templates, returns NULL. 121 TemplateDecl *getAsTemplateDecl() const; 122 123 /// \brief Retrieve the the underlying, overloaded function template 124 // declarations that this template name refers to, if known. 125 /// 126 /// \returns The set of overloaded function templates that this template 127 /// name refers to, if known. If the template name does not refer to a 128 /// specific set of function templates because it is a dependent name or 129 /// refers to a single template, returns NULL. 130 OverloadedTemplateStorage *getAsOverloadedTemplate() const { 131 return Storage.dyn_cast<OverloadedTemplateStorage *>(); 132 } 133 134 /// \brief Retrieve the underlying qualified template name 135 /// structure, if any. 136 QualifiedTemplateName *getAsQualifiedTemplateName() const { 137 return Storage.dyn_cast<QualifiedTemplateName *>(); 138 } 139 140 /// \brief Retrieve the underlying dependent template name 141 /// structure, if any. 142 DependentTemplateName *getAsDependentTemplateName() const { 143 return Storage.dyn_cast<DependentTemplateName *>(); 144 } 145 146 /// \brief Determines whether this is a dependent template name. 147 bool isDependent() const; 148 149 /// \brief Print the template name. 150 /// 151 /// \param OS the output stream to which the template name will be 152 /// printed. 153 /// 154 /// \param SuppressNNS if true, don't print the 155 /// nested-name-specifier that precedes the template name (if it has 156 /// one). 157 void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, 158 bool SuppressNNS = false) const; 159 160 /// \brief Debugging aid that dumps the template name to standard 161 /// error. 162 void dump() const; 163 164 void Profile(llvm::FoldingSetNodeID &ID) { 165 ID.AddPointer(Storage.getOpaqueValue()); 166 } 167 168 /// \brief Retrieve the template name as a void pointer. 169 void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } 170 171 /// \brief Build a template name from a void pointer. 172 static TemplateName getFromVoidPointer(void *Ptr) { 173 return TemplateName(Ptr); 174 } 175}; 176 177/// Insertion operator for diagnostics. This allows sending TemplateName's 178/// into a diagnostic with <<. 179const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 180 TemplateName N); 181 182/// \brief Represents a template name that was expressed as a 183/// qualified name. 184/// 185/// This kind of template name refers to a template name that was 186/// preceded by a nested name specifier, e.g., \c std::vector. Here, 187/// the nested name specifier is "std::" and the template name is the 188/// declaration for "vector". The QualifiedTemplateName class is only 189/// used to provide "sugar" for template names that were expressed 190/// with a qualified name, and has no semantic meaning. In this 191/// manner, it is to TemplateName what ElaboratedType is to Type, 192/// providing extra syntactic sugar for downstream clients. 193class QualifiedTemplateName : public llvm::FoldingSetNode { 194 /// \brief The nested name specifier that qualifies the template name. 195 /// 196 /// The bit is used to indicate whether the "template" keyword was 197 /// present before the template name itself. Note that the 198 /// "template" keyword is always redundant in this case (otherwise, 199 /// the template name would be a dependent name and we would express 200 /// this name with DependentTemplateName). 201 llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier; 202 203 /// \brief The template declaration or set of overloaded function templates 204 /// that this qualified name refers to. 205 TemplateDecl *Template; 206 207 friend class ASTContext; 208 209 QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, 210 TemplateDecl *Template) 211 : Qualifier(NNS, TemplateKeyword? 1 : 0), 212 Template(Template) { } 213 214public: 215 /// \brief Return the nested name specifier that qualifies this name. 216 NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } 217 218 /// \brief Whether the template name was prefixed by the "template" 219 /// keyword. 220 bool hasTemplateKeyword() const { return Qualifier.getInt(); } 221 222 /// \brief The template declaration that this qualified name refers 223 /// to. 224 TemplateDecl *getDecl() const { return Template; } 225 226 /// \brief The template declaration to which this qualified name 227 /// refers. 228 TemplateDecl *getTemplateDecl() const { return Template; } 229 230 void Profile(llvm::FoldingSetNodeID &ID) { 231 Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl()); 232 } 233 234 static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, 235 bool TemplateKeyword, TemplateDecl *Template) { 236 ID.AddPointer(NNS); 237 ID.AddBoolean(TemplateKeyword); 238 ID.AddPointer(Template); 239 } 240}; 241 242/// \brief Represents a dependent template name that cannot be 243/// resolved prior to template instantiation. 244/// 245/// This kind of template name refers to a dependent template name, 246/// including its nested name specifier (if any). For example, 247/// DependentTemplateName can refer to "MetaFun::template apply", 248/// where "MetaFun::" is the nested name specifier and "apply" is the 249/// template name referenced. The "template" keyword is implied. 250class DependentTemplateName : public llvm::FoldingSetNode { 251 /// \brief The nested name specifier that qualifies the template 252 /// name. 253 /// 254 /// The bit stored in this qualifier describes whether the \c Name field 255 /// is interpreted as an IdentifierInfo pointer (when clear) or as an 256 /// overloaded operator kind (when set). 257 llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier; 258 259 /// \brief The dependent template name. 260 union { 261 /// \brief The identifier template name. 262 /// 263 /// Only valid when the bit on \c Qualifier is clear. 264 const IdentifierInfo *Identifier; 265 266 /// \brief The overloaded operator name. 267 /// 268 /// Only valid when the bit on \c Qualifier is set. 269 OverloadedOperatorKind Operator; 270 }; 271 272 /// \brief The canonical template name to which this dependent 273 /// template name refers. 274 /// 275 /// The canonical template name for a dependent template name is 276 /// another dependent template name whose nested name specifier is 277 /// canonical. 278 TemplateName CanonicalTemplateName; 279 280 friend class ASTContext; 281 282 DependentTemplateName(NestedNameSpecifier *Qualifier, 283 const IdentifierInfo *Identifier) 284 : Qualifier(Qualifier, false), Identifier(Identifier), 285 CanonicalTemplateName(this) { } 286 287 DependentTemplateName(NestedNameSpecifier *Qualifier, 288 const IdentifierInfo *Identifier, 289 TemplateName Canon) 290 : Qualifier(Qualifier, false), Identifier(Identifier), 291 CanonicalTemplateName(Canon) { } 292 293 DependentTemplateName(NestedNameSpecifier *Qualifier, 294 OverloadedOperatorKind Operator) 295 : Qualifier(Qualifier, true), Operator(Operator), 296 CanonicalTemplateName(this) { } 297 298 DependentTemplateName(NestedNameSpecifier *Qualifier, 299 OverloadedOperatorKind Operator, 300 TemplateName Canon) 301 : Qualifier(Qualifier, true), Operator(Operator), 302 CanonicalTemplateName(Canon) { } 303 304public: 305 /// \brief Return the nested name specifier that qualifies this name. 306 NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } 307 308 /// \brief Determine whether this template name refers to an identifier. 309 bool isIdentifier() const { return !Qualifier.getInt(); } 310 311 /// \brief Returns the identifier to which this template name refers. 312 const IdentifierInfo *getIdentifier() const { 313 assert(isIdentifier() && "Template name isn't an identifier?"); 314 return Identifier; 315 } 316 317 /// \brief Determine whether this template name refers to an overloaded 318 /// operator. 319 bool isOverloadedOperator() const { return Qualifier.getInt(); } 320 321 /// \brief Return the overloaded operator to which this template name refers. 322 OverloadedOperatorKind getOperator() const { 323 assert(isOverloadedOperator() && 324 "Template name isn't an overloaded operator?"); 325 return Operator; 326 } 327 328 void Profile(llvm::FoldingSetNodeID &ID) { 329 if (isIdentifier()) 330 Profile(ID, getQualifier(), getIdentifier()); 331 else 332 Profile(ID, getQualifier(), getOperator()); 333 } 334 335 static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, 336 const IdentifierInfo *Identifier) { 337 ID.AddPointer(NNS); 338 ID.AddBoolean(false); 339 ID.AddPointer(Identifier); 340 } 341 342 static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, 343 OverloadedOperatorKind Operator) { 344 ID.AddPointer(NNS); 345 ID.AddBoolean(true); 346 ID.AddInteger(Operator); 347 } 348}; 349 350} // end namespace clang. 351 352namespace llvm { 353 354/// \brief The clang::TemplateName class is effectively a pointer. 355template<> 356class PointerLikeTypeTraits<clang::TemplateName> { 357public: 358 static inline void *getAsVoidPointer(clang::TemplateName TN) { 359 return TN.getAsVoidPointer(); 360 } 361 362 static inline clang::TemplateName getFromVoidPointer(void *Ptr) { 363 return clang::TemplateName::getFromVoidPointer(Ptr); 364 } 365 366 // No bits are available! 367 enum { NumLowBitsAvailable = 0 }; 368}; 369 370} // end namespace llvm. 371 372#endif 373