blob: 780afd4468b3a5451223ac4ab4b971658b4cc07b [file] [log] [blame]
Douglas Gregoraa6af222009-03-25 00:27:28 +00001//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/
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// This file implements C++ template instantiation for declarations.
10//
11//===----------------------------------------------------------------------===/
12#include "Sema.h"
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/StmtVisitor.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/ExprCXX.h"
18#include "clang/Parse/DeclSpec.h"
19#include "clang/Lex/Preprocessor.h" // for the identifier table
20#include "llvm/Support/Compiler.h"
21using namespace clang;
22
23namespace {
24 class VISIBILITY_HIDDEN TemplateExprInstantiator
25 : public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> {
26 Sema &SemaRef;
27 const TemplateArgument *TemplateArgs;
28 unsigned NumTemplateArgs;
29
30 public:
31 typedef Sema::OwningExprResult OwningExprResult;
32
33 TemplateExprInstantiator(Sema &SemaRef,
34 const TemplateArgument *TemplateArgs,
35 unsigned NumTemplateArgs)
36 : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
37 NumTemplateArgs(NumTemplateArgs) { }
38
39 // FIXME: Once we get closer to completion, replace these
40 // manually-written declarations with automatically-generated ones
41 // from clang/AST/StmtNodes.def.
42 OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
43 OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
44 OwningExprResult VisitParenExpr(ParenExpr *E);
45 OwningExprResult VisitUnaryOperator(UnaryOperator *E);
46 OwningExprResult VisitBinaryOperator(BinaryOperator *E);
47 OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
48 OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
49 OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
50 OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
51 OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
52 OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
53
54 // Base case. I'm supposed to ignore this.
55 Sema::OwningExprResult VisitStmt(Stmt *S) {
56 S->dump();
57 assert(false && "Cannot instantiate this kind of expression");
58 return SemaRef.ExprError();
59 }
60 };
61}
62
63Sema::OwningExprResult
64TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
65 return SemaRef.Clone(E);
66}
67
68Sema::OwningExprResult
69TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
70 Decl *D = E->getDecl();
71 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
72 assert(NTTP->getDepth() == 0 && "No nested templates yet");
73 const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
74 QualType T = Arg.getIntegralType();
75 if (T->isCharType() || T->isWideCharType())
76 return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
77 Arg.getAsIntegral()->getZExtValue(),
78 T->isWideCharType(),
79 T,
80 E->getSourceRange().getBegin()));
81 else if (T->isBooleanType())
82 return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
83 Arg.getAsIntegral()->getBoolValue(),
84 T,
85 E->getSourceRange().getBegin()));
86
87 return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
88 *Arg.getAsIntegral(),
89 T,
90 E->getSourceRange().getBegin()));
91 } else
92 assert(false && "Can't handle arbitrary declaration references");
93
94 return SemaRef.ExprError();
95}
96
97Sema::OwningExprResult
98TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
99 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
100 if (SubExpr.isInvalid())
101 return SemaRef.ExprError();
102
103 return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
104 E->getLParen(), E->getRParen(),
105 (Expr *)SubExpr.release()));
106}
107
108Sema::OwningExprResult
109TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
110 Sema::OwningExprResult Arg = Visit(E->getSubExpr());
111 if (Arg.isInvalid())
112 return SemaRef.ExprError();
113
114 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
115 E->getOpcode(),
116 move(Arg));
117}
118
119Sema::OwningExprResult
120TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
121 Sema::OwningExprResult LHS = Visit(E->getLHS());
122 if (LHS.isInvalid())
123 return SemaRef.ExprError();
124
125 Sema::OwningExprResult RHS = Visit(E->getRHS());
126 if (RHS.isInvalid())
127 return SemaRef.ExprError();
128
129 Sema::OwningExprResult Result
130 = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
131 E->getOpcode(),
132 (Expr *)LHS.get(),
133 (Expr *)RHS.get());
134 if (Result.isInvalid())
135 return SemaRef.ExprError();
136
137 LHS.release();
138 RHS.release();
139 return move(Result);
140}
141
142Sema::OwningExprResult
143TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
144 Sema::OwningExprResult First = Visit(E->getArg(0));
145 if (First.isInvalid())
146 return SemaRef.ExprError();
147
148 Expr *Args[2] = { (Expr *)First.get(), 0 };
149
150 Sema::OwningExprResult Second(SemaRef);
151 if (E->getNumArgs() == 2) {
152 Second = Visit(E->getArg(1));
153
154 if (Second.isInvalid())
155 return SemaRef.ExprError();
156
157 Args[1] = (Expr *)Second.get();
158 }
159
160 if (!E->isTypeDependent()) {
161 // Since our original expression was not type-dependent, we do not
162 // perform lookup again at instantiation time (C++ [temp.dep]p1).
163 // Instead, we just build the new overloaded operator call
164 // expression.
165 First.release();
166 Second.release();
167 // FIXME: Don't reuse the callee here. We need to instantiate it.
168 return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
169 SemaRef.Context,
170 E->getOperator(),
171 E->getCallee(),
172 Args, E->getNumArgs(),
173 E->getType(),
174 E->getOperatorLoc()));
175 }
176
177 bool isPostIncDec = E->getNumArgs() == 2 &&
178 (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
179 if (E->getNumArgs() == 1 || isPostIncDec) {
180 if (!Args[0]->getType()->isOverloadableType()) {
181 // The argument is not of overloadable type, so try to create a
182 // built-in unary operation.
183 UnaryOperator::Opcode Opc
184 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
185
186 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
187 move(First));
188 }
189
190 // Fall through to perform overload resolution
191 } else {
192 assert(E->getNumArgs() == 2 && "Expected binary operation");
193
194 Sema::OwningExprResult Result(SemaRef);
195 if (!Args[0]->getType()->isOverloadableType() &&
196 !Args[1]->getType()->isOverloadableType()) {
197 // Neither of the arguments is an overloadable type, so try to
198 // create a built-in binary operation.
199 BinaryOperator::Opcode Opc =
200 BinaryOperator::getOverloadedOpcode(E->getOperator());
201 Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
202 Args[0], Args[1]);
203 if (Result.isInvalid())
204 return SemaRef.ExprError();
205
206 First.release();
207 Second.release();
208 return move(Result);
209 }
210
211 // Fall through to perform overload resolution.
212 }
213
214 // Compute the set of functions that were found at template
215 // definition time.
216 Sema::FunctionSet Functions;
217 DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
218 OverloadedFunctionDecl *Overloads
219 = cast<OverloadedFunctionDecl>(DRE->getDecl());
220
221 // FIXME: Do we have to check
222 // IsAcceptableNonMemberOperatorCandidate for each of these?
223 for (OverloadedFunctionDecl::function_iterator
224 F = Overloads->function_begin(),
225 FEnd = Overloads->function_end();
226 F != FEnd; ++F)
227 Functions.insert(*F);
228
229 // Add any functions found via argument-dependent lookup.
230 DeclarationName OpName
231 = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
232 SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
233
234 // Create the overloaded operator invocation.
235 if (E->getNumArgs() == 1 || isPostIncDec) {
236 UnaryOperator::Opcode Opc
237 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
238 return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
239 Functions, move(First));
240 }
241
242 // FIXME: This would be far less ugly if CreateOverloadedBinOp took
243 // in ExprArg arguments!
244 BinaryOperator::Opcode Opc =
245 BinaryOperator::getOverloadedOpcode(E->getOperator());
246 OwningExprResult Result
247 = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
248 Functions, Args[0], Args[1]);
249
250 if (Result.isInvalid())
251 return SemaRef.ExprError();
252
253 First.release();
254 Second.release();
255 return move(Result);
256}
257
258Sema::OwningExprResult
259TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
260 Sema::OwningExprResult Cond = Visit(E->getCond());
261 if (Cond.isInvalid())
262 return SemaRef.ExprError();
263
264 // FIXME: use getLHS() and cope with NULLness
265 Sema::OwningExprResult True = Visit(E->getTrueExpr());
266 if (True.isInvalid())
267 return SemaRef.ExprError();
268
269 Sema::OwningExprResult False = Visit(E->getFalseExpr());
270 if (False.isInvalid())
271 return SemaRef.ExprError();
272
273 if (!E->isTypeDependent()) {
274 // Since our original expression was not type-dependent, we do not
275 // perform lookup again at instantiation time (C++ [temp.dep]p1).
276 // Instead, we just build the new conditional operator call expression.
277 return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
278 Cond.takeAs<Expr>(),
279 True.takeAs<Expr>(),
280 False.takeAs<Expr>(),
281 E->getType()));
282 }
283
284
285 return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
286 /*FIXME*/E->getFalseExpr()->getLocStart(),
287 move(Cond), move(True), move(False));
288}
289
290Sema::OwningExprResult
291TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
292 bool isSizeOf = E->isSizeOf();
293
294 if (E->isArgumentType()) {
295 QualType T = E->getArgumentType();
296 if (T->isDependentType()) {
297 T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
298 /*FIXME*/E->getOperatorLoc(),
299 &SemaRef.PP.getIdentifierTable().get("sizeof"));
300 if (T.isNull())
301 return SemaRef.ExprError();
302 }
303
304 return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
305 E->getSourceRange());
306 }
307
308 Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
309 if (Arg.isInvalid())
310 return SemaRef.ExprError();
311
312 Sema::OwningExprResult Result
313 = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
314 isSizeOf, E->getSourceRange());
315 if (Result.isInvalid())
316 return SemaRef.ExprError();
317
318 Arg.release();
319 return move(Result);
320}
321
322Sema::OwningExprResult
323TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
324 CXXScopeSpec SS = SemaRef.InstantiateScopeSpecifier(E->begin(), E->size(),
325 E->getQualifierRange(),
326 TemplateArgs,
327 NumTemplateArgs);
328 if (SS.isInvalid() || SS.isEmpty())
329 return SemaRef.ExprError();
330
331 // FIXME: We're passing in a NULL scope, because
332 // ActOnDeclarationNameExpr doesn't actually use the scope when we
333 // give it a non-empty scope specifier. Investigate whether it would
334 // be better to refactor ActOnDeclarationNameExpr.
335 return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
336 E->getDeclName(),
337 /*HasTrailingLParen=*/false,
338 &SS,
339 /*FIXME:isAddressOfOperand=*/false);
340}
341
342Sema::OwningExprResult
343TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
344 CXXTemporaryObjectExpr *E) {
345 QualType T = E->getType();
346 if (T->isDependentType()) {
347 T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
348 E->getTypeBeginLoc(), DeclarationName());
349 if (T.isNull())
350 return SemaRef.ExprError();
351 }
352
353 llvm::SmallVector<Expr *, 16> Args;
354 Args.reserve(E->getNumArgs());
355 bool Invalid = false;
356 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
357 ArgEnd = E->arg_end();
358 Arg != ArgEnd; ++Arg) {
359 OwningExprResult InstantiatedArg = Visit(*Arg);
360 if (InstantiatedArg.isInvalid()) {
361 Invalid = true;
362 break;
363 }
364
365 Args.push_back((Expr *)InstantiatedArg.release());
366 }
367
368 if (!Invalid) {
369 SourceLocation CommaLoc;
370 // FIXME: HACK!
371 if (Args.size() > 1)
372 CommaLoc
373 = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
374 Sema::OwningExprResult Result(
375 SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
376 /*, FIXME*/),
377 T.getAsOpaquePtr(),
378 /*FIXME*/E->getTypeBeginLoc(),
379 Sema::MultiExprArg(SemaRef,
380 (void**)&Args[0],
381 Args.size()),
382 /*HACK*/&CommaLoc,
383 E->getSourceRange().getEnd()));
384 // At this point, Args no longer owns the arguments, no matter what.
385 return move(Result);
386 }
387
388 // Clean up the instantiated arguments.
389 // FIXME: Would rather do this with RAII.
390 for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
391 SemaRef.DeleteExpr(Args[Idx]);
392
393 return SemaRef.ExprError();
394}
395
396Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
397 ImplicitCastExpr *E) {
398 assert(!E->isTypeDependent() && "Implicit casts must have known types");
399
400 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
401 if (SubExpr.isInvalid())
402 return SemaRef.ExprError();
403
404 ImplicitCastExpr *ICE =
405 new (SemaRef.Context) ImplicitCastExpr(E->getType(),
406 (Expr *)SubExpr.release(),
407 E->isLvalueCast());
408 return SemaRef.Owned(ICE);
409}
410
411Sema::OwningExprResult
412Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
413 unsigned NumTemplateArgs) {
414 TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);
415 return Instantiator.Visit(E);
416}