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