|  | //===--- 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(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) { | 
|  | return SemaRef.Clone(E); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) { | 
|  | return SemaRef.Clone(E); | 
|  | } | 
|  |  | 
|  | 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); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) { | 
|  | return SemaRef.Clone(E); | 
|  | } | 
|  |  | 
|  | 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, | 
|  | 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)); | 
|  | } | 
|  |  | 
|  | 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>(), | 
|  | 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) { | 
|  | 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, | 
|  | /*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(), | 
|  | TemplateArgs); | 
|  | 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); | 
|  | } | 
|  |  | 
|  | 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); | 
|  | } | 
|  |  | 
|  | 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); | 
|  | } | 
|  |  | 
|  | 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); | 
|  | for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(), | 
|  | ArgEnd = E->arg_end(); | 
|  | Arg != ArgEnd; ++Arg) { | 
|  | OwningExprResult ArgInst = Visit(*Arg); | 
|  | if (ArgInst.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | Args.push_back(ArgInst.takeAs<Expr>()); | 
|  | } | 
|  |  | 
|  | return SemaRef.Owned(CXXConstructExpr::Create(SemaRef.Context, T, | 
|  | E->getConstructor(), | 
|  | E->isElidable(), | 
|  | Args.takeAs<Expr>(), | 
|  | Args.size())); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXFunctionalCastExpr( | 
|  | CXXFunctionalCastExpr *E) { | 
|  | // Instantiate the type that we're casting to. | 
|  | QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(), | 
|  | TemplateArgs, | 
|  | E->getTypeBeginLoc(), | 
|  | DeclarationName()); | 
|  | if (ExplicitTy.isNull()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | // Instantiate the subexpression. | 
|  | OwningExprResult SubExpr = Visit(E->getSubExpr()); | 
|  | if (SubExpr.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | // FIXME: The end of the type's source range is wrong | 
|  | Expr *Sub = SubExpr.takeAs<Expr>(); | 
|  | return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()), | 
|  | ExplicitTy.getAsOpaquePtr(), | 
|  | /*FIXME:*/E->getTypeBeginLoc(), | 
|  | Sema::MultiExprArg(SemaRef, | 
|  | (void **)&Sub, | 
|  | 1), | 
|  | 0, | 
|  | E->getRParenLoc()); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { | 
|  | return SemaRef.Clone(E); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXNewExpr(CXXNewExpr *E) { | 
|  | // Instantiate the type that we're allocating | 
|  | QualType AllocType = SemaRef.InstantiateType(E->getAllocatedType(), | 
|  | TemplateArgs, | 
|  | /*FIXME:*/E->getSourceRange().getBegin(), | 
|  | DeclarationName()); | 
|  | if (AllocType.isNull()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | // Instantiate the size of the array we're allocating (if any). | 
|  | OwningExprResult ArraySize = SemaRef.InstantiateExpr(E->getArraySize(), | 
|  | TemplateArgs); | 
|  | if (ArraySize.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | // Instantiate the placement arguments (if any). | 
|  | ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef); | 
|  | for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) { | 
|  | OwningExprResult Arg = Visit(E->getPlacementArg(I)); | 
|  | if (Arg.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | PlacementArgs.push_back(Arg.take()); | 
|  | } | 
|  |  | 
|  | // Instantiate the constructor arguments (if any). | 
|  | ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef); | 
|  | for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) { | 
|  | OwningExprResult Arg = Visit(E->getConstructorArg(I)); | 
|  | if (Arg.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | ConstructorArgs.push_back(Arg.take()); | 
|  | } | 
|  |  | 
|  | return SemaRef.BuildCXXNew(E->getSourceRange().getBegin(), | 
|  | E->isGlobalNew(), | 
|  | /*FIXME*/SourceLocation(), | 
|  | move_arg(PlacementArgs), | 
|  | /*FIXME*/SourceLocation(), | 
|  | E->isParenTypeId(), | 
|  | AllocType, | 
|  | /*FIXME*/E->getSourceRange().getBegin(), | 
|  | SourceRange(), | 
|  | move(ArraySize), | 
|  | /*FIXME*/SourceLocation(), | 
|  | Sema::MultiExprArg(SemaRef, | 
|  | ConstructorArgs.take(), | 
|  | ConstructorArgs.size()), | 
|  | E->getSourceRange().getEnd()); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXDeleteExpr(CXXDeleteExpr *E) { | 
|  | OwningExprResult Operand = Visit(E->getArgument()); | 
|  | if (Operand.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | return SemaRef.ActOnCXXDelete(E->getSourceRange().getBegin(), | 
|  | E->isGlobalDelete(), | 
|  | E->isArrayForm(), | 
|  | move(Operand)); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { | 
|  | QualType T = SemaRef.InstantiateType(E->getQueriedType(), TemplateArgs, | 
|  | /*FIXME*/E->getSourceRange().getBegin(), | 
|  | DeclarationName()); | 
|  | if (T.isNull()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | SourceLocation FakeLParenLoc | 
|  | = SemaRef.PP.getLocForEndOfToken(E->getSourceRange().getBegin()); | 
|  | return SemaRef.ActOnUnaryTypeTrait(E->getTrait(), | 
|  | E->getSourceRange().getBegin(), | 
|  | /*FIXME*/FakeLParenLoc, | 
|  | T.getAsOpaquePtr(), | 
|  | E->getSourceRange().getEnd()); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) { | 
|  | NestedNameSpecifier *NNS | 
|  | = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(), | 
|  | E->getQualifierRange(), | 
|  | TemplateArgs); | 
|  | if (!NNS) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | CXXScopeSpec SS; | 
|  | SS.setRange(E->getQualifierRange()); | 
|  | SS.setScopeRep(NNS); | 
|  | return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, | 
|  | E->getLocation(), | 
|  | E->getDecl()->getDeclName(), | 
|  | /*Trailing lparen=*/false, | 
|  | &SS, | 
|  | /*FIXME:*/false); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXExprWithTemporaries( | 
|  | CXXExprWithTemporaries *E) { | 
|  | OwningExprResult SubExpr = Visit(E->getSubExpr()); | 
|  | if (SubExpr.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | return SemaRef.ActOnFinishFullExpr(move(SubExpr)); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr( | 
|  | CXXUnresolvedConstructExpr *E) { | 
|  | QualType T = SemaRef.InstantiateType(E->getTypeAsWritten(), TemplateArgs, | 
|  | E->getTypeBeginLoc(), | 
|  | DeclarationName()); | 
|  | if (T.isNull()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef); | 
|  | llvm::SmallVector<SourceLocation, 8> FakeCommaLocs; | 
|  | for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(), | 
|  | ArgEnd = E->arg_end(); | 
|  | Arg != ArgEnd; ++Arg) { | 
|  | OwningExprResult InstArg = Visit(*Arg); | 
|  | if (InstArg.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | FakeCommaLocs.push_back( | 
|  | SemaRef.PP.getLocForEndOfToken((*Arg)->getSourceRange().getEnd())); | 
|  | Args.push_back(InstArg.takeAs<Expr>()); | 
|  | } | 
|  |  | 
|  | // FIXME: The end of the type range isn't exactly correct. | 
|  | // FIXME: we're faking the locations of the commas | 
|  | return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc(), | 
|  | E->getLParenLoc()), | 
|  | T.getAsOpaquePtr(), | 
|  | E->getLParenLoc(), | 
|  | move_arg(Args), | 
|  | &FakeCommaLocs.front(), | 
|  | E->getRParenLoc()); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitCXXUnresolvedMemberExpr( | 
|  | CXXUnresolvedMemberExpr *E) { | 
|  | // Instantiate the base of the expression. | 
|  | OwningExprResult Base = Visit(E->getBase()); | 
|  | if (Base.isInvalid()) | 
|  | return SemaRef.ExprError(); | 
|  |  | 
|  | // FIXME: Instantiate the declaration name. | 
|  | return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0, | 
|  | move(Base), E->getOperatorLoc(), | 
|  | E->isArrow()? tok::arrow | 
|  | : tok::period, | 
|  | E->getMemberLoc(), | 
|  | /*FIXME:*/*E->getMember().getAsIdentifierInfo(), | 
|  | /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0)); | 
|  | } | 
|  |  | 
|  | //---------------------------------------------------------------------------- | 
|  | // Objective-C Expressions | 
|  | //---------------------------------------------------------------------------- | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCMessageExpr(ObjCMessageExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCProtocolExpr(ObjCProtocolExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | TemplateExprInstantiator::VisitObjCSuperExpr(ObjCSuperExpr *E) { | 
|  | assert(false && "FIXME: Template instantiations for ObjC expressions"); | 
|  | return SemaRef.ExprError(); | 
|  | } | 
|  |  | 
|  | Sema::OwningExprResult | 
|  | Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) { | 
|  | if (!E) | 
|  | return Owned((Expr *)0); | 
|  |  | 
|  | TemplateExprInstantiator Instantiator(*this, TemplateArgs); | 
|  | return Instantiator.Visit(E); | 
|  | } |