TemplateName.cpp revision 6b5415196327fa8ef00f028ba175fafef1738ae1
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/DeclTemplate.h" 16#include "clang/AST/NestedNameSpecifier.h" 17#include "clang/AST/PrettyPrinter.h" 18#include "clang/Basic/Diagnostic.h" 19#include "clang/Basic/LangOptions.h" 20#include "llvm/Support/raw_ostream.h" 21using namespace clang; 22using namespace llvm; 23 24TemplateName::NameKind TemplateName::getKind() const { 25 if (Storage.is<TemplateDecl *>()) 26 return Template; 27 if (Storage.is<OverloadedTemplateStorage *>()) 28 return OverloadedTemplate; 29 if (Storage.is<QualifiedTemplateName *>()) 30 return QualifiedTemplate; 31 assert(Storage.is<DependentTemplateName *>() && "There's a case unhandled!"); 32 return DependentTemplate; 33} 34 35TemplateDecl *TemplateName::getAsTemplateDecl() const { 36 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) 37 return Template; 38 39 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) 40 return QTN->getTemplateDecl(); 41 42 return 0; 43} 44 45bool TemplateName::isDependent() const { 46 if (TemplateDecl *Template = getAsTemplateDecl()) { 47 if (isa<TemplateTemplateParmDecl>(Template)) 48 return true; 49 // FIXME: Hack, getDeclContext() can be null if Template is still 50 // initializing due to PCH reading, so we check it before using it. 51 // Should probably modify TemplateSpecializationType to allow constructing 52 // it without the isDependent() checking. 53 return Template->getDeclContext() && 54 Template->getDeclContext()->isDependentContext(); 55 } 56 57 assert(!getAsOverloadedTemplate() && 58 "overloaded templates shouldn't survive to here"); 59 60 return true; 61} 62 63void 64TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, 65 bool SuppressNNS) const { 66 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) 67 OS << Template; 68 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { 69 if (!SuppressNNS) 70 QTN->getQualifier()->print(OS, Policy); 71 if (QTN->hasTemplateKeyword()) 72 OS << "template "; 73 OS << QTN->getDecl(); 74 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { 75 if (!SuppressNNS && DTN->getQualifier()) 76 DTN->getQualifier()->print(OS, Policy); 77 OS << "template "; 78 79 if (DTN->isIdentifier()) 80 OS << DTN->getIdentifier()->getName(); 81 else 82 OS << "operator " << getOperatorSpelling(DTN->getOperator()); 83 } 84} 85 86const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 87 TemplateName N) { 88 std::string NameStr; 89 raw_string_ostream OS(NameStr); 90 LangOptions LO; 91 LO.CPlusPlus = true; 92 LO.Bool = true; 93 N.print(OS, PrintingPolicy(LO)); 94 OS.flush(); 95 return DB << NameStr; 96} 97 98void TemplateName::dump() const { 99 LangOptions LO; // FIXME! 100 LO.CPlusPlus = true; 101 LO.Bool = true; 102 print(llvm::errs(), PrintingPolicy(LO)); 103} 104