TemplateBase.cpp revision bd054dba8a3023821f2a0951b0fae05e3522a7c9
1//===--- TemplateBase.cpp - Common template AST class implementation ------===// 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 implements common classes used throughout C++ template 11// representations. 12// 13//===----------------------------------------------------------------------===// 14 15#include "llvm/ADT/FoldingSet.h" 16#include "clang/AST/TemplateBase.h" 17#include "clang/AST/DeclBase.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/AST/Expr.h" 20#include "clang/AST/TypeLoc.h" 21#include "clang/Basic/Diagnostic.h" 22 23using namespace clang; 24 25//===----------------------------------------------------------------------===// 26// TemplateArgument Implementation 27//===----------------------------------------------------------------------===// 28 29/// \brief Construct a template argument pack. 30void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs, 31 bool CopyArgs) { 32 assert(isNull() && "Must call setArgumentPack on a null argument"); 33 34 Kind = Pack; 35 Args.NumArgs = NumArgs; 36 Args.CopyArgs = CopyArgs; 37 if (!Args.CopyArgs) { 38 Args.Args = args; 39 return; 40 } 41 42 // FIXME: Allocate in ASTContext 43 Args.Args = new TemplateArgument[NumArgs]; 44 for (unsigned I = 0; I != Args.NumArgs; ++I) 45 Args.Args[I] = args[I]; 46} 47 48void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 49 ASTContext &Context) const { 50 ID.AddInteger(Kind); 51 switch (Kind) { 52 case Null: 53 break; 54 55 case Type: 56 getAsType().Profile(ID); 57 break; 58 59 case Declaration: 60 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0); 61 break; 62 63 case Template: 64 if (TemplateTemplateParmDecl *TTP 65 = dyn_cast_or_null<TemplateTemplateParmDecl>( 66 getAsTemplate().getAsTemplateDecl())) { 67 ID.AddBoolean(true); 68 ID.AddInteger(TTP->getDepth()); 69 ID.AddInteger(TTP->getPosition()); 70 } else { 71 ID.AddBoolean(false); 72 ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate()) 73 .getAsVoidPointer()); 74 } 75 break; 76 77 case Integral: 78 getAsIntegral()->Profile(ID); 79 getIntegralType().Profile(ID); 80 break; 81 82 case Expression: 83 getAsExpr()->Profile(ID, Context, true); 84 break; 85 86 case Pack: 87 ID.AddInteger(Args.NumArgs); 88 for (unsigned I = 0; I != Args.NumArgs; ++I) 89 Args.Args[I].Profile(ID, Context); 90 } 91} 92 93//===----------------------------------------------------------------------===// 94// TemplateArgumentLoc Implementation 95//===----------------------------------------------------------------------===// 96 97SourceRange TemplateArgumentLoc::getSourceRange() const { 98 switch (Argument.getKind()) { 99 case TemplateArgument::Expression: 100 return getSourceExpression()->getSourceRange(); 101 102 case TemplateArgument::Declaration: 103 return getSourceDeclExpression()->getSourceRange(); 104 105 case TemplateArgument::Type: 106 return getTypeSourceInfo()->getTypeLoc().getSourceRange(); 107 108 case TemplateArgument::Template: 109 if (getTemplateQualifierRange().isValid()) 110 return SourceRange(getTemplateQualifierRange().getBegin(), 111 getTemplateNameLoc()); 112 return SourceRange(getTemplateNameLoc()); 113 114 case TemplateArgument::Integral: 115 case TemplateArgument::Pack: 116 case TemplateArgument::Null: 117 return SourceRange(); 118 } 119 120 // Silence bonus gcc warning. 121 return SourceRange(); 122} 123 124const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 125 const TemplateArgument &Arg) { 126 switch (Arg.getKind()) { 127 case TemplateArgument::Null: 128 return DB; 129 130 case TemplateArgument::Type: 131 return DB << Arg.getAsType(); 132 133 case TemplateArgument::Declaration: 134 return DB << Arg.getAsDecl(); 135 136 case TemplateArgument::Integral: 137 return DB << Arg.getAsIntegral()->toString(10); 138 139 case TemplateArgument::Template: 140 return DB << Arg.getAsTemplate(); 141 142 case TemplateArgument::Expression: { 143 // This shouldn't actually ever happen, so it's okay that we're 144 // regurgitating an expression here. 145 // FIXME: We're guessing at LangOptions! 146 llvm::SmallString<32> Str; 147 llvm::raw_svector_ostream OS(Str); 148 LangOptions LangOpts; 149 LangOpts.CPlusPlus = true; 150 PrintingPolicy Policy(LangOpts); 151 Arg.getAsExpr()->printPretty(OS, 0, Policy); 152 return DB << OS.str(); 153 } 154 155 case TemplateArgument::Pack: 156 // FIXME: Format arguments in a list! 157 return DB << "<parameter pack>"; 158 } 159 160 return DB; 161} 162