1 //===--- TemplateBase.cpp - Common template AST class implementation ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements common classes used throughout C++ template
13 //===----------------------------------------------------------------------===//
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"
23 using namespace clang;
25 //===----------------------------------------------------------------------===//
26 // TemplateArgument Implementation
27 //===----------------------------------------------------------------------===//
29 /// \brief Construct a template argument pack.
30 void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
32 assert(isNull() && "Must call setArgumentPack on a null argument");
35 Args.NumArgs = NumArgs;
36 Args.CopyArgs = CopyArgs;
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];
48 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
49 ASTContext &Context) const {
56 getAsType().Profile(ID);
60 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
64 if (TemplateTemplateParmDecl *TTP
65 = dyn_cast_or_null<TemplateTemplateParmDecl>(
66 getAsTemplate().getAsTemplateDecl())) {
68 ID.AddInteger(TTP->getDepth());
69 ID.AddInteger(TTP->getPosition());
72 ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
78 getAsIntegral()->Profile(ID);
79 getIntegralType().Profile(ID);
83 getAsExpr()->Profile(ID, Context, true);
87 ID.AddInteger(Args.NumArgs);
88 for (unsigned I = 0; I != Args.NumArgs; ++I)
89 Args.Args[I].Profile(ID, Context);
93 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
94 if (getKind() != Other.getKind()) return false;
102 return TypeOrValue == Other.TypeOrValue;
105 return getIntegralType() == Other.getIntegralType() &&
106 *getAsIntegral() == *Other.getAsIntegral();
109 if (Args.NumArgs != Other.Args.NumArgs) return false;
110 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
111 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
116 // Suppress warnings.
120 //===----------------------------------------------------------------------===//
121 // TemplateArgumentLoc Implementation
122 //===----------------------------------------------------------------------===//
124 SourceRange TemplateArgumentLoc::getSourceRange() const {
125 switch (Argument.getKind()) {
126 case TemplateArgument::Expression:
127 return getSourceExpression()->getSourceRange();
129 case TemplateArgument::Declaration:
130 return getSourceDeclExpression()->getSourceRange();
132 case TemplateArgument::Type:
133 if (TypeSourceInfo *TSI = getTypeSourceInfo())
134 return TSI->getTypeLoc().getSourceRange();
136 return SourceRange();
138 case TemplateArgument::Template:
139 if (getTemplateQualifierRange().isValid())
140 return SourceRange(getTemplateQualifierRange().getBegin(),
141 getTemplateNameLoc());
142 return SourceRange(getTemplateNameLoc());
144 case TemplateArgument::Integral:
145 case TemplateArgument::Pack:
146 case TemplateArgument::Null:
147 return SourceRange();
150 // Silence bonus gcc warning.
151 return SourceRange();
154 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
155 const TemplateArgument &Arg) {
156 switch (Arg.getKind()) {
157 case TemplateArgument::Null:
158 // This is bad, but not as bad as crashing because of argument
160 return DB << "(null template argument)";
162 case TemplateArgument::Type:
163 return DB << Arg.getAsType();
165 case TemplateArgument::Declaration:
166 return DB << Arg.getAsDecl();
168 case TemplateArgument::Integral:
169 return DB << Arg.getAsIntegral()->toString(10);
171 case TemplateArgument::Template:
172 return DB << Arg.getAsTemplate();
174 case TemplateArgument::Expression: {
175 // This shouldn't actually ever happen, so it's okay that we're
176 // regurgitating an expression here.
177 // FIXME: We're guessing at LangOptions!
178 llvm::SmallString<32> Str;
179 llvm::raw_svector_ostream OS(Str);
180 LangOptions LangOpts;
181 LangOpts.CPlusPlus = true;
182 PrintingPolicy Policy(LangOpts);
183 Arg.getAsExpr()->printPretty(OS, 0, Policy);
184 return DB << OS.str();
187 case TemplateArgument::Pack:
188 // FIXME: Format arguments in a list!
189 return DB << "<parameter pack>";