diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
new file mode 100644
index 0000000..780afd4
--- /dev/null
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -0,0 +1,416 @@
+//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl 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 declarations.
+//
+//===----------------------------------------------------------------------===/
+#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/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 TemplateArgument *TemplateArgs;
+    unsigned NumTemplateArgs;
+
+  public:
+    typedef Sema::OwningExprResult OwningExprResult;
+
+    TemplateExprInstantiator(Sema &SemaRef, 
+                             const TemplateArgument *TemplateArgs,
+                             unsigned NumTemplateArgs)
+      : SemaRef(SemaRef), TemplateArgs(TemplateArgs), 
+        NumTemplateArgs(NumTemplateArgs) { }
+
+    // FIXME: Once we get closer to completion, replace these
+    // manually-written declarations with automatically-generated ones
+    // from clang/AST/StmtNodes.def.
+    OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
+    OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
+    OwningExprResult VisitParenExpr(ParenExpr *E);
+    OwningExprResult VisitUnaryOperator(UnaryOperator *E);
+    OwningExprResult VisitBinaryOperator(BinaryOperator *E);
+    OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
+    OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
+    OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
+    OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
+    OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
+    OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
+      
+    // Base case. I'm supposed to ignore this.
+    Sema::OwningExprResult VisitStmt(Stmt *S) { 
+      S->dump();
+      assert(false && "Cannot instantiate this kind of expression");
+      return SemaRef.ExprError(); 
+    }
+  };
+}
+
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
+  return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
+  Decl *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()));
+    else if (T->isBooleanType())
+      return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
+                                          Arg.getAsIntegral()->getBoolValue(),
+                                                 T, 
+                                       E->getSourceRange().getBegin()));
+
+    return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
+                                                 *Arg.getAsIntegral(),
+                                                 T, 
+                                       E->getSourceRange().getBegin()));
+  } else
+    assert(false && "Can't handle arbitrary declaration references");
+
+  return SemaRef.ExprError();
+}
+
+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::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::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.
+    First.release();
+    Second.release();
+    // FIXME: Don't reuse the callee here. We need to instantiate it.
+    return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
+                                                       SemaRef.Context, 
+                                                       E->getOperator(),
+                                                       E->getCallee(), 
+                                                       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::VisitConditionalOperator(ConditionalOperator *E) {
+  Sema::OwningExprResult Cond = Visit(E->getCond());
+  if (Cond.isInvalid())
+    return SemaRef.ExprError();
+
+  // FIXME: use getLHS() and cope with NULLness
+  Sema::OwningExprResult True = Visit(E->getTrueExpr());
+  if (True.isInvalid())
+    return SemaRef.ExprError();
+
+  Sema::OwningExprResult False = Visit(E->getFalseExpr());
+  if (False.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>(),
+                                                           True.takeAs<Expr>(), 
+                                                           False.takeAs<Expr>(),
+                                                           E->getType()));
+  }
+
+
+  return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
+                                    /*FIXME*/E->getFalseExpr()->getLocStart(),
+                                    move(Cond), move(True), move(False));
+}
+
+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, NumTemplateArgs,
+                                  /*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) {
+  CXXScopeSpec SS = SemaRef.InstantiateScopeSpecifier(E->begin(), E->size(),
+                                                      E->getQualifierRange(),
+                                                      TemplateArgs,
+                                                      NumTemplateArgs);
+  if (SS.isInvalid() || SS.isEmpty())
+    return SemaRef.ExprError();
+
+  // 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, NumTemplateArgs,
+                                E->getTypeBeginLoc(), DeclarationName());
+    if (T.isNull())
+      return SemaRef.ExprError();
+  }
+
+  llvm::SmallVector<Expr *, 16> Args;
+  Args.reserve(E->getNumArgs());
+  bool Invalid = false;
+  for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(), 
+                                         ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    OwningExprResult InstantiatedArg = Visit(*Arg);
+    if (InstantiatedArg.isInvalid()) {
+      Invalid = true;
+      break;
+    }
+
+    Args.push_back((Expr *)InstantiatedArg.release());
+  }
+
+  if (!Invalid) {
+    SourceLocation CommaLoc;
+    // FIXME: HACK!
+    if (Args.size() > 1)
+      CommaLoc 
+        = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
+    Sema::OwningExprResult Result(
+      SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
+                                                    /*, FIXME*/),
+                                        T.getAsOpaquePtr(),
+                                        /*FIXME*/E->getTypeBeginLoc(),
+                                        Sema::MultiExprArg(SemaRef,
+                                                           (void**)&Args[0],
+                                                           Args.size()),
+                                        /*HACK*/&CommaLoc,
+                                        E->getSourceRange().getEnd()));
+    // At this point, Args no longer owns the arguments, no matter what.
+    return move(Result);
+  }
+
+  // Clean up the instantiated arguments.
+  // FIXME: Would rather do this with RAII.
+  for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
+    SemaRef.DeleteExpr(Args[Idx]);
+
+  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 
+Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
+                      unsigned NumTemplateArgs) {
+  TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);
+  return Instantiator.Visit(E);
+}
