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