blob: 0bf9f2fb7c333edd5fc5740b2a661781f88675b8 [file] [log] [blame]
John McCall275c10a2009-10-29 07:48:15 +00001//===--- 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"
Douglas Gregor74295b32009-11-23 12:52:47 +000018#include "clang/AST/DeclTemplate.h"
John McCall275c10a2009-10-29 07:48:15 +000019#include "clang/AST/Expr.h"
John McCall833ca992009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
Douglas Gregora9333192010-05-08 17:41:32 +000021#include "clang/Basic/Diagnostic.h"
John McCall275c10a2009-10-29 07:48:15 +000022
23using namespace clang;
24
25//===----------------------------------------------------------------------===//
26// TemplateArgument Implementation
27//===----------------------------------------------------------------------===//
28
John McCall275c10a2009-10-29 07:48:15 +000029/// \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
Douglas Gregor788cd062009-11-11 01:00:40 +000063 case Template:
Douglas Gregor74295b32009-11-23 12:52:47 +000064 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 }
Douglas Gregor788cd062009-11-11 01:00:40 +000075 break;
76
John McCall275c10a2009-10-29 07:48:15 +000077 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}
John McCall833ca992009-10-29 08:12:44 +000092
93//===----------------------------------------------------------------------===//
94// TemplateArgumentLoc Implementation
95//===----------------------------------------------------------------------===//
96
John McCall828bff22009-10-29 18:45:58 +000097SourceRange TemplateArgumentLoc::getSourceRange() const {
John McCall833ca992009-10-29 08:12:44 +000098 switch (Argument.getKind()) {
99 case TemplateArgument::Expression:
John McCall828bff22009-10-29 18:45:58 +0000100 return getSourceExpression()->getSourceRange();
Douglas Gregor788cd062009-11-11 01:00:40 +0000101
John McCall833ca992009-10-29 08:12:44 +0000102 case TemplateArgument::Declaration:
John McCall828bff22009-10-29 18:45:58 +0000103 return getSourceDeclExpression()->getSourceRange();
Douglas Gregor788cd062009-11-11 01:00:40 +0000104
John McCall828bff22009-10-29 18:45:58 +0000105 case TemplateArgument::Type:
John McCalla93c9342009-12-07 02:54:59 +0000106 return getTypeSourceInfo()->getTypeLoc().getFullSourceRange();
Douglas Gregor788cd062009-11-11 01:00:40 +0000107
108 case TemplateArgument::Template:
109 if (getTemplateQualifierRange().isValid())
110 return SourceRange(getTemplateQualifierRange().getBegin(),
111 getTemplateNameLoc());
112 return SourceRange(getTemplateNameLoc());
113
John McCall833ca992009-10-29 08:12:44 +0000114 case TemplateArgument::Integral:
115 case TemplateArgument::Pack:
116 case TemplateArgument::Null:
John McCall828bff22009-10-29 18:45:58 +0000117 return SourceRange();
John McCall833ca992009-10-29 08:12:44 +0000118 }
119
120 // Silence bonus gcc warning.
John McCall828bff22009-10-29 18:45:58 +0000121 return SourceRange();
John McCall833ca992009-10-29 08:12:44 +0000122}
Douglas Gregora9333192010-05-08 17:41:32 +0000123
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}