Newer
Older
//===--- SemaTemplateInstantiateExpr.cpp - C++ Template Expr Instantiation ===/
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===/
//
// This file implements C++ template instantiation for expressions.
//
//===----------------------------------------------------------------------===/
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Designator.h"
#include "clang/Lex/Preprocessor.h" // for the identifier table
#include "llvm/Support/Compiler.h"
using namespace clang;
namespace {
class VISIBILITY_HIDDEN TemplateExprInstantiator
: public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> {
Sema &SemaRef;
const TemplateArgumentList &TemplateArgs;
public:
typedef Sema::OwningExprResult OwningExprResult;
TemplateExprInstantiator(Sema &SemaRef,
const TemplateArgumentList &TemplateArgs)
: SemaRef(SemaRef), TemplateArgs(TemplateArgs) { }
// Declare VisitXXXStmt nodes for all of the expression kinds.
#define EXPR(Type, Base) OwningExprResult Visit##Type(Type *S);
#define STMT(Type, Base)
#include "clang/AST/StmtNodes.def"
// Base case. We can't get here.
Sema::OwningExprResult VisitStmt(Stmt *S) {
S->dump();
assert(false && "Cannot instantiate this kind of expression");
return SemaRef.ExprError();
}
};
}
// Base case. We can't get here.
Sema::OwningExprResult TemplateExprInstantiator::VisitExpr(Expr *E) {
E->dump();
assert(false && "Cannot instantiate this kind of expression");
return SemaRef.ExprError();
}
Sebastian Redl
committed
Sema::OwningExprResult
TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
return SemaRef.Clone(E);
}
Sebastian Redl
committed
Sema::OwningExprResult
TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
return SemaRef.Clone(E);
}
Douglas Gregor
committed
Sema::OwningExprResult
TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
return SemaRef.Clone(E);
}
Sebastian Redl
committed
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
UnresolvedFunctionNameExpr *E) {
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
NamedDecl *D = E->getDecl();
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
assert(NTTP->getDepth() == 0 && "No nested templates yet");
const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
QualType T = Arg.getIntegralType();
if (T->isCharType() || T->isWideCharType())
return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
Arg.getAsIntegral()->getZExtValue(),
T->isWideCharType(),
T,
E->getSourceRange().getBegin()));
if (T->isBooleanType())
return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
Arg.getAsIntegral()->getBoolValue(),
T,
E->getSourceRange().getBegin()));
assert(Arg.getAsIntegral()->getBitWidth() == SemaRef.Context.getIntWidth(T));
return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
*Arg.getAsIntegral(),
T,
E->getSourceRange().getBegin()));
}
if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) {
// FIXME: instantiate each decl in the overload set
return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Ovl,
SemaRef.Context.OverloadTy,
E->getLocation(),
false, false));
ValueDecl *NewD
= dyn_cast_or_null<ValueDecl>(SemaRef.InstantiateCurrentDeclRef(D));
if (!NewD)
return SemaRef.ExprError();
// FIXME: Build QualifiedDeclRefExpr?
QualType T = NewD->getType();
return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
Douglas Gregor
committed
T.getNonReferenceType(),
E->getLocation(),
T->isDependentType(),
T->isDependentType()));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
E->getLParen(), E->getRParen(),
(Expr *)SubExpr.release()));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
Sema::OwningExprResult Arg = Visit(E->getSubExpr());
if (Arg.isInvalid())
return SemaRef.ExprError();
return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
E->getOpcode(),
move(Arg));
}
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
Sema::OwningExprResult
TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
Sema::OwningExprResult LHS = Visit(E->getLHS());
if (LHS.isInvalid())
return SemaRef.ExprError();
Sema::OwningExprResult RHS = Visit(E->getRHS());
if (RHS.isInvalid())
return SemaRef.ExprError();
// Since the overloaded array-subscript operator (operator[]) can
// only be a member function, we can make several simplifying
// assumptions here:
// 1) Normal name lookup (from the current scope) will not ever
// find any declarations of operator[] that won't also be found be
// member operator lookup, so it is safe to pass a NULL Scope
// during the instantiation to avoid the lookup entirely.
//
// 2) Neither normal name lookup nor argument-dependent lookup at
// template definition time will find any operators that won't be
// found at template instantiation time, so we do not need to
// cache the results of name lookup as we do for the binary
// operators.
SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
/*FIXME:*/LLocFake,
move(RHS),
E->getRBracketLoc());
}
Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) {
// Instantiate callee
OwningExprResult Callee = Visit(E->getCallee());
if (Callee.isInvalid())
return SemaRef.ExprError();
// Instantiate arguments
ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
OwningExprResult Arg = Visit(E->getArg(I));
if (Arg.isInvalid())
return SemaRef.ExprError();
FakeCommaLocs.push_back(
SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Args.push_back(Arg.takeAs<Expr>());
}
SourceLocation FakeLParenLoc
= ((Expr *)Callee.get())->getSourceRange().getBegin();
return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee),
/*FIXME:*/FakeLParenLoc,
move_arg(Args),
/*FIXME:*/&FakeCommaLocs.front(),
E->getRParenLoc());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitMemberExpr(MemberExpr *E) {
// Instantiate the base of the expression.
OwningExprResult Base = Visit(E->getBase());
if (Base.isInvalid())
return SemaRef.ExprError();
// FIXME: Handle declaration names here
SourceLocation FakeOperatorLoc =
SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
move(Base),
/*FIXME*/FakeOperatorLoc,
E->isArrow()? tok::arrow
: tok::period,
E->getMemberLoc(),
/*FIXME:*/*E->getMemberDecl()->getIdentifier(),
/*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
SourceLocation FakeTypeLoc
= SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
FakeTypeLoc,
DeclarationName());
if (T.isNull())
return SemaRef.ExprError();
OwningExprResult Init = Visit(E->getInitializer());
if (Init.isInvalid())
return SemaRef.ExprError();
return SemaRef.ActOnCompoundLiteral(E->getLParenLoc(),
T.getAsOpaquePtr(),
/*FIXME*/E->getLParenLoc(),
move(Init));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
Sema::OwningExprResult LHS = Visit(E->getLHS());
if (LHS.isInvalid())
return SemaRef.ExprError();
Sema::OwningExprResult RHS = Visit(E->getRHS());
if (RHS.isInvalid())
return SemaRef.ExprError();
Sema::OwningExprResult Result
= SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
E->getOpcode(),
(Expr *)LHS.get(),
(Expr *)RHS.get());
if (Result.isInvalid())
return SemaRef.ExprError();
LHS.release();
RHS.release();
return move(Result);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCompoundAssignOperator(
CompoundAssignOperator *E) {
return VisitBinaryOperator(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
Sema::OwningExprResult First = Visit(E->getArg(0));
if (First.isInvalid())
return SemaRef.ExprError();
Expr *Args[2] = { (Expr *)First.get(), 0 };
Sema::OwningExprResult Second(SemaRef);
if (E->getNumArgs() == 2) {
Second = Visit(E->getArg(1));
if (Second.isInvalid())
return SemaRef.ExprError();
Args[1] = (Expr *)Second.get();
}
if (!E->isTypeDependent()) {
// Since our original expression was not type-dependent, we do not
// perform lookup again at instantiation time (C++ [temp.dep]p1).
// Instead, we just build the new overloaded operator call
// expression.
OwningExprResult Callee = Visit(E->getCallee());
if (Callee.isInvalid())
return SemaRef.ExprError();
First.release();
Second.release();
return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
SemaRef.Context,
E->getOperator(),
Callee.takeAs<Expr>(),
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
Args, E->getNumArgs(),
E->getType(),
E->getOperatorLoc()));
}
bool isPostIncDec = E->getNumArgs() == 2 &&
(E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
if (E->getNumArgs() == 1 || isPostIncDec) {
if (!Args[0]->getType()->isOverloadableType()) {
// The argument is not of overloadable type, so try to create a
// built-in unary operation.
UnaryOperator::Opcode Opc
= UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
move(First));
}
// Fall through to perform overload resolution
} else {
assert(E->getNumArgs() == 2 && "Expected binary operation");
Sema::OwningExprResult Result(SemaRef);
if (!Args[0]->getType()->isOverloadableType() &&
!Args[1]->getType()->isOverloadableType()) {
// Neither of the arguments is an overloadable type, so try to
// create a built-in binary operation.
BinaryOperator::Opcode Opc =
BinaryOperator::getOverloadedOpcode(E->getOperator());
Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
Args[0], Args[1]);
if (Result.isInvalid())
return SemaRef.ExprError();
First.release();
Second.release();
return move(Result);
}
// Fall through to perform overload resolution.
}
// Compute the set of functions that were found at template
// definition time.
Sema::FunctionSet Functions;
DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
OverloadedFunctionDecl *Overloads
= cast<OverloadedFunctionDecl>(DRE->getDecl());
// FIXME: Do we have to check
// IsAcceptableNonMemberOperatorCandidate for each of these?
for (OverloadedFunctionDecl::function_iterator
F = Overloads->function_begin(),
FEnd = Overloads->function_end();
F != FEnd; ++F)
Functions.insert(*F);
// Add any functions found via argument-dependent lookup.
DeclarationName OpName
= SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
// Create the overloaded operator invocation.
if (E->getNumArgs() == 1 || isPostIncDec) {
UnaryOperator::Opcode Opc
= UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
Functions, move(First));
}
// FIXME: This would be far less ugly if CreateOverloadedBinOp took in ExprArg
// arguments!
BinaryOperator::Opcode Opc =
BinaryOperator::getOverloadedOpcode(E->getOperator());
OwningExprResult Result
= SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
Functions, Args[0], Args[1]);
if (Result.isInvalid())
return SemaRef.ExprError();
First.release();
Second.release();
return move(Result);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
VarDecl *Var
= cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
SemaRef.CurContext,
TemplateArgs));
if (!Var)
return SemaRef.ExprError();
SemaRef.CurrentInstantiationScope->InstantiatedLocal(E->getVarDecl(), Var);
return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
E->getStartLoc(),
SourceLocation(),
Var));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
Sema::OwningExprResult Cond = Visit(E->getCond());
if (Cond.isInvalid())
return SemaRef.ExprError();
Sema::OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(),
TemplateArgs);
if (LHS.isInvalid())
return SemaRef.ExprError();
Sema::OwningExprResult RHS = Visit(E->getRHS());
if (RHS.isInvalid())
return SemaRef.ExprError();
if (!E->isTypeDependent()) {
// Since our original expression was not type-dependent, we do not
// perform lookup again at instantiation time (C++ [temp.dep]p1).
// Instead, we just build the new conditional operator call expression.
return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
Cond.takeAs<Expr>(),
LHS.takeAs<Expr>(),
RHS.takeAs<Expr>(),
E->getType()));
}
return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
/*FIXME*/E->getFalseExpr()->getLocStart(),
move(Cond), move(LHS), move(RHS));
Sema::OwningExprResult
TemplateExprInstantiator::VisitAddrLabelExpr(AddrLabelExpr *E) {
return SemaRef.ActOnAddrLabel(E->getAmpAmpLoc(),
E->getLabelLoc(),
E->getLabel()->getID());
}
Sema::OwningExprResult TemplateExprInstantiator::VisitStmtExpr(StmtExpr *E) {
Sema::OwningStmtResult SubStmt
= SemaRef.InstantiateCompoundStmt(E->getSubStmt(), TemplateArgs, true);
if (SubStmt.isInvalid())
return SemaRef.ExprError();
return SemaRef.ActOnStmtExpr(E->getLParenLoc(), move(SubStmt),
E->getRParenLoc());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregor
committed
assert(false && "__builtin_types_compatible_p is not legal in C++");
return SemaRef.ExprError();
Sema::OwningExprResult
TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
OwningExprResult SubExpr = Visit(E->getExpr(I));
if (SubExpr.isInvalid())
return SemaRef.ExprError();
SubExprs.push_back(SubExpr.takeAs<Expr>());
}
// Find the declaration for __builtin_shufflevector
const IdentifierInfo &Name
= SemaRef.Context.Idents.get("__builtin_shufflevector");
TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
DeclContext::lookup_result Lookup
= TUDecl->lookup(SemaRef.Context, DeclarationName(&Name));
assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
// Build a reference to the __builtin_shufflevector builtin
FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
E->getBuiltinLoc(),
false, false);
SemaRef.UsualUnaryConversions(Callee);
// Build the CallExpr
CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
SubExprs.takeAs<Expr>(),
SubExprs.size(),
Builtin->getResultType(),
E->getRParenLoc());
OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
// Type-check the __builtin_shufflevector expression.
OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
if (Result.isInvalid())
return SemaRef.ExprError();
OwnedCall.release();
return move(Result);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitChooseExpr(ChooseExpr *E) {
OwningExprResult Cond = Visit(E->getCond());
if (Cond.isInvalid())
return SemaRef.ExprError();
OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(), TemplateArgs);
if (LHS.isInvalid())
return SemaRef.ExprError();
OwningExprResult RHS = Visit(E->getRHS());
if (RHS.isInvalid())
return SemaRef.ExprError();
return SemaRef.ActOnChooseExpr(E->getBuiltinLoc(),
move(Cond), move(LHS), move(RHS),
E->getRParenLoc());
}
Sema::OwningExprResult TemplateExprInstantiator::VisitVAArgExpr(VAArgExpr *E) {
OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
SourceLocation FakeTypeLoc
= SemaRef.PP.getLocForEndOfToken(E->getSubExpr()->getSourceRange()
.getEnd());
QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
/*FIXME:*/FakeTypeLoc,
DeclarationName());
if (T.isNull())
return SemaRef.ExprError();
return SemaRef.ActOnVAArg(E->getBuiltinLoc(), move(SubExpr),
T.getAsOpaquePtr(), E->getRParenLoc());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitInitListExpr(InitListExpr *E) {
ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
OwningExprResult Init = Visit(E->getInit(I));
if (Init.isInvalid())
return SemaRef.ExprError();
Inits.push_back(Init.takeAs<Expr>());
}
return SemaRef.ActOnInitList(E->getLBraceLoc(), move_arg(Inits),
E->getRBraceLoc());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
Designation Desig;
// Instantiate the initializer value
OwningExprResult Init = Visit(E->getInit());
if (Init.isInvalid())
return SemaRef.ExprError();
// Instantiate the designators.
ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
DEnd = E->designators_end();
D != DEnd; ++D) {
if (D->isFieldDesignator()) {
Desig.AddDesignator(Designator::getField(D->getFieldName(),
D->getDotLoc(),
D->getFieldLoc()));
continue;
}
if (D->isArrayDesignator()) {
OwningExprResult Index = Visit(E->getArrayIndex(*D));
if (Index.isInvalid())
return SemaRef.ExprError();
Desig.AddDesignator(Designator::getArray(Index.get(),
D->getLBracketLoc()));
ArrayExprs.push_back(Index.release());
continue;
}
assert(D->isArrayRangeDesignator() && "New kind of designator?");
OwningExprResult Start = Visit(E->getArrayRangeStart(*D));
if (Start.isInvalid())
return SemaRef.ExprError();
OwningExprResult End = Visit(E->getArrayRangeEnd(*D));
if (End.isInvalid())
return SemaRef.ExprError();
Desig.AddDesignator(Designator::getArrayRange(Start.get(),
End.get(),
D->getLBracketLoc(),
D->getEllipsisLoc()));
ArrayExprs.push_back(Start.release());
ArrayExprs.push_back(End.release());
}
OwningExprResult Result =
SemaRef.ActOnDesignatedInitializer(Desig,
E->getEqualOrColonLoc(),
E->usesGNUSyntax(),
move(Init));
if (Result.isInvalid())
return SemaRef.ExprError();
ArrayExprs.take();
return move(Result);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitImplicitValueInitExpr(
ImplicitValueInitExpr *E) {
assert(!E->isTypeDependent() && !E->isValueDependent() &&
"ImplicitValueInitExprs are never dependent");
return SemaRef.Clone(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
OwningExprResult Base = Visit(E->getBase());
if (Base.isInvalid())
return SemaRef.ExprError();
SourceLocation FakeOperatorLoc =
SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
move(Base),
/*FIXME*/FakeOperatorLoc,
tok::period,
E->getAccessorLoc(),
E->getAccessor(),
/*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitBlockExpr(BlockExpr *E) {
assert(false && "FIXME:Template instantiation for blocks is unimplemented");
return SemaRef.ExprError();
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
assert(false && "FIXME:Template instantiation for blocks is unimplemented");
return SemaRef.ExprError();
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
bool isSizeOf = E->isSizeOf();
if (E->isArgumentType()) {
QualType T = E->getArgumentType();
if (T->isDependentType()) {
T = SemaRef.InstantiateType(T, TemplateArgs,
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
/*FIXME*/E->getOperatorLoc(),
&SemaRef.PP.getIdentifierTable().get("sizeof"));
if (T.isNull())
return SemaRef.ExprError();
}
return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
E->getSourceRange());
}
Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
if (Arg.isInvalid())
return SemaRef.ExprError();
Sema::OwningExprResult Result
= SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
isSizeOf, E->getSourceRange());
if (Result.isInvalid())
return SemaRef.ExprError();
Arg.release();
return move(Result);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
NestedNameSpecifier *NNS
= SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange(),
if (!NNS)
return SemaRef.ExprError();
CXXScopeSpec SS;
SS.setRange(E->getQualifierRange());
SS.setScopeRep(NNS);
// FIXME: We're passing in a NULL scope, because
// ActOnDeclarationNameExpr doesn't actually use the scope when we
// give it a non-empty scope specifier. Investigate whether it would
// be better to refactor ActOnDeclarationNameExpr.
return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
E->getDeclName(),
/*HasTrailingLParen=*/false,
&SS,
/*FIXME:isAddressOfOperand=*/false);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
CXXTemporaryObjectExpr *E) {
QualType T = E->getType();
if (T->isDependentType()) {
T = SemaRef.InstantiateType(T, TemplateArgs,
E->getTypeBeginLoc(), DeclarationName());
if (T.isNull())
return SemaRef.ExprError();
}
ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Args.reserve(E->getNumArgs());
for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
ArgEnd = E->arg_end();
Arg != ArgEnd; ++Arg) {
OwningExprResult InstantiatedArg = Visit(*Arg);
if (InstantiatedArg.isInvalid())
return SemaRef.ExprError();
Args.push_back((Expr *)InstantiatedArg.release());
}
SourceLocation CommaLoc;
// FIXME: HACK!
if (Args.size() > 1) {
Expr *First = (Expr *)Args[0];
CommaLoc
= SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
/*, FIXME*/),
T.getAsOpaquePtr(),
/*FIXME*/E->getTypeBeginLoc(),
move_arg(Args),
/*HACK*/&CommaLoc,
E->getSourceRange().getEnd());
Sema::OwningExprResult TemplateExprInstantiator::VisitCastExpr(CastExpr *E) {
assert(false && "Cannot instantiate abstract CastExpr");
return SemaRef.ExprError();
}
Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
ImplicitCastExpr *E) {
assert(!E->isTypeDependent() && "Implicit casts must have known types");
Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
ImplicitCastExpr *ICE =
new (SemaRef.Context) ImplicitCastExpr(E->getType(),
(Expr *)SubExpr.release(),
E->isLvalueCast());
return SemaRef.Owned(ICE);
}
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
Sema::OwningExprResult
TemplateExprInstantiator::VisitExplicitCastExpr(ExplicitCastExpr *E) {
assert(false && "Cannot instantiate abstract ExplicitCastExpr");
return SemaRef.ExprError();
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCStyleCastExpr(CStyleCastExpr *E) {
// Instantiate the type that we're casting to.
SourceLocation TypeStartLoc
= SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
TemplateArgs,
TypeStartLoc,
DeclarationName());
if (ExplicitTy.isNull())
return SemaRef.ExprError();
// Instantiate the subexpression.
OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
return SemaRef.ActOnCastExpr(E->getLParenLoc(),
ExplicitTy.getAsOpaquePtr(),
E->getRParenLoc(),
move(SubExpr));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
return VisitCallExpr(E);
}
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
// Figure out which cast operator we're dealing with.
tok::TokenKind Kind;
switch (E->getStmtClass()) {
case Stmt::CXXStaticCastExprClass:
Kind = tok::kw_static_cast;
break;
case Stmt::CXXDynamicCastExprClass:
Kind = tok::kw_dynamic_cast;
break;
case Stmt::CXXReinterpretCastExprClass:
Kind = tok::kw_reinterpret_cast;
break;
case Stmt::CXXConstCastExprClass:
Kind = tok::kw_const_cast;
break;
default:
assert(false && "Invalid C++ named cast");
return SemaRef.ExprError();
}
// Instantiate the type that we're casting to.
SourceLocation TypeStartLoc
= SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
TemplateArgs,
TypeStartLoc,
DeclarationName());
if (ExplicitTy.isNull())
return SemaRef.ExprError();
// Instantiate the subexpression.
OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
SourceLocation FakeLAngleLoc
= SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
SourceLocation FakeRParenLoc
= SemaRef.PP.getLocForEndOfToken(
E->getSubExpr()->getSourceRange().getEnd());
return SemaRef.ActOnCXXNamedCast(E->getOperatorLoc(), Kind,
/*FIXME:*/FakeLAngleLoc,
ExplicitTy.getAsOpaquePtr(),
/*FIXME:*/FakeRAngleLoc,
/*FIXME:*/FakeRAngleLoc,
move(SubExpr),
/*FIXME:*/FakeRParenLoc);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
return VisitCXXNamedCastExpr(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
return VisitCXXNamedCastExpr(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXReinterpretCastExpr(
CXXReinterpretCastExpr *E) {
return VisitCXXNamedCastExpr(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
return VisitCXXNamedCastExpr(E);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
QualType ThisType =
cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
CXXThisExpr *TE =
new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
return SemaRef.Owned(TE);
}
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
if (E->isTypeOperand()) {
QualType T = SemaRef.InstantiateType(E->getTypeOperand(),
TemplateArgs,
/*FIXME*/E->getSourceRange().getBegin(),
DeclarationName());
if (T.isNull())
return SemaRef.ExprError();
return SemaRef.ActOnCXXTypeid(E->getSourceRange().getBegin(),
/*FIXME*/E->getSourceRange().getBegin(),
true, T.getAsOpaquePtr(),
E->getSourceRange().getEnd());
}
OwningExprResult Operand = Visit(E->getExprOperand());
if (Operand.isInvalid())
return SemaRef.ExprError();
OwningExprResult Result
= SemaRef.ActOnCXXTypeid(E->getSourceRange().getBegin(),
/*FIXME*/E->getSourceRange().getBegin(),
false, Operand.get(),
E->getSourceRange().getEnd());
if (Result.isInvalid())
return SemaRef.ExprError();
Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
return move(Result);
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXThrowExpr(CXXThrowExpr *E) {
OwningExprResult SubExpr(SemaRef, (void *)0);
if (E->getSubExpr()) {
SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
}
return SemaRef.ActOnCXXThrow(E->getThrowLoc(), move(SubExpr));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
assert(false &&
"FIXME: Instantiation for default arguments is unimplemented");
return SemaRef.ExprError();
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXBindTemporaryExpr(
CXXBindTemporaryExpr *E) {
OwningExprResult SubExpr = Visit(E->getSubExpr());
if (SubExpr.isInvalid())
return SemaRef.ExprError();
return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) {
assert(!cast<CXXRecordDecl>(E->getConstructor()->getDeclContext())
->isDependentType() && "Dependent constructor shouldn't be here");
QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
/*FIXME*/E->getSourceRange().getBegin(),
DeclarationName());
if (T.isNull())
return SemaRef.ExprError();
ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);