TemplateName.cpp revision 1aee05d08b2184acadeb36de300e216390780d6c
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#include "clang/AST/TemplateName.h" 15#include "clang/AST/TemplateBase.h" 16#include "clang/AST/DeclTemplate.h" 17#include "clang/AST/NestedNameSpecifier.h" 18#include "clang/AST/PrettyPrinter.h" 19#include "clang/Basic/Diagnostic.h" 20#include "clang/Basic/LangOptions.h" 21#include "llvm/Support/raw_ostream.h" 22using namespace clang; 23using namespace llvm; 24 25TemplateArgument 26SubstTemplateTemplateParmPackStorage::getArgumentPack() const { 27 return TemplateArgument(Arguments, size()); 28} 29 30void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID) { 31 Profile(ID, Context, Parameter, TemplateArgument(Arguments, size())); 32} 33 34void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID, 35 ASTContext &Context, 36 TemplateTemplateParmDecl *Parameter, 37 const TemplateArgument &ArgPack) { 38 ID.AddPointer(Parameter); 39 ArgPack.Profile(ID, Context); 40} 41 42TemplateName::NameKind TemplateName::getKind() const { 43 if (Storage.is<TemplateDecl *>()) 44 return Template; 45 if (Storage.is<DependentTemplateName *>()) 46 return DependentTemplate; 47 if (Storage.is<QualifiedTemplateName *>()) 48 return QualifiedTemplate; 49 50 return getAsOverloadedTemplate()? OverloadedTemplate 51 : SubstTemplateTemplateParmPack; 52} 53 54TemplateDecl *TemplateName::getAsTemplateDecl() const { 55 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) 56 return Template; 57 58 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) 59 return QTN->getTemplateDecl(); 60 61 return 0; 62} 63 64bool TemplateName::isDependent() const { 65 if (TemplateDecl *Template = getAsTemplateDecl()) { 66 if (isa<TemplateTemplateParmDecl>(Template)) 67 return true; 68 // FIXME: Hack, getDeclContext() can be null if Template is still 69 // initializing due to PCH reading, so we check it before using it. 70 // Should probably modify TemplateSpecializationType to allow constructing 71 // it without the isDependent() checking. 72 return Template->getDeclContext() && 73 Template->getDeclContext()->isDependentContext(); 74 } 75 76 assert(!getAsOverloadedTemplate() && 77 "overloaded templates shouldn't survive to here"); 78 79 return true; 80} 81 82bool TemplateName::containsUnexpandedParameterPack() const { 83 if (TemplateDecl *Template = getAsTemplateDecl()) { 84 if (TemplateTemplateParmDecl *TTP 85 = dyn_cast<TemplateTemplateParmDecl>(Template)) 86 return TTP->isParameterPack(); 87 88 return false; 89 } 90 91 if (DependentTemplateName *DTN = getAsDependentTemplateName()) 92 return DTN->getQualifier() && 93 DTN->getQualifier()->containsUnexpandedParameterPack(); 94 95 return getAsSubstTemplateTemplateParmPack() != 0; 96} 97 98void 99TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, 100 bool SuppressNNS) const { 101 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) 102 OS << Template; 103 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { 104 if (!SuppressNNS) 105 QTN->getQualifier()->print(OS, Policy); 106 if (QTN->hasTemplateKeyword()) 107 OS << "template "; 108 OS << QTN->getDecl(); 109 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { 110 if (!SuppressNNS && DTN->getQualifier()) 111 DTN->getQualifier()->print(OS, Policy); 112 OS << "template "; 113 114 if (DTN->isIdentifier()) 115 OS << DTN->getIdentifier()->getName(); 116 else 117 OS << "operator " << getOperatorSpelling(DTN->getOperator()); 118 } else if (SubstTemplateTemplateParmPackStorage *SubstPack 119 = getAsSubstTemplateTemplateParmPack()) 120 OS << SubstPack->getParameterPack()->getNameAsString(); 121} 122 123const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 124 TemplateName N) { 125 std::string NameStr; 126 raw_string_ostream OS(NameStr); 127 LangOptions LO; 128 LO.CPlusPlus = true; 129 LO.Bool = true; 130 N.print(OS, PrintingPolicy(LO)); 131 OS.flush(); 132 return DB << NameStr; 133} 134 135void TemplateName::dump() const { 136 LangOptions LO; // FIXME! 137 LO.CPlusPlus = true; 138 LO.Bool = true; 139 print(llvm::errs(), PrintingPolicy(LO)); 140} 141