Implement template instantiation for several more kinds of expressions:
  - C++ function casts, e.g., T(foo)
  - sizeof(), alignof()

More importantly, this allows us to verify that we're performing
overload resolution during template instantiation, with
argument-dependent lookup and the "cached" results of name lookup from
the template definition.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66947 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0855932..c04006c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1220,6 +1220,50 @@
   return CheckSizeOfAlignOfOperand(E->getType(), OpLoc, ExprRange, false);
 }
 
+/// \brief Build a sizeof or alignof expression given a type operand.
+Action::OwningExprResult 
+Sema::CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc, 
+                              bool isSizeOf, SourceRange R) {
+  if (T.isNull())
+    return ExprError();
+
+  if (!T->isDependentType() &&
+      CheckSizeOfAlignOfOperand(T, OpLoc, R, isSizeOf))
+    return ExprError();
+
+  // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
+  return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, T,
+                                               Context.getSizeType(), OpLoc,
+                                               R.getEnd()));
+}
+
+/// \brief Build a sizeof or alignof expression given an expression
+/// operand.
+Action::OwningExprResult 
+Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc, 
+                              bool isSizeOf, SourceRange R) {
+  // Verify that the operand is valid.
+  bool isInvalid = false;
+  if (E->isTypeDependent()) {
+    // Delay type-checking for type-dependent expressions.
+  } else if (!isSizeOf) {
+    isInvalid = CheckAlignOfExpr(E, OpLoc, R);
+  } else if (E->isBitField()) {  // C99 6.5.3.4p1.
+    Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0;
+    isInvalid = true;
+  } else {
+    isInvalid = CheckSizeOfAlignOfOperand(E->getType(), OpLoc, R, true);
+  }
+
+  if (isInvalid)
+    return ExprError();
+
+  // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
+  return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, E,
+                                               Context.getSizeType(), OpLoc,
+                                               R.getEnd()));
+}
+
 /// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and
 /// the same for @c alignof and @c __alignof
 /// Note that the ArgRange is invalid if isType is false.
@@ -1229,42 +1273,20 @@
   // If error parsing type, ignore.
   if (TyOrEx == 0) return ExprError();
 
-  QualType ArgTy;
-  SourceRange Range;
   if (isType) {
-    ArgTy = QualType::getFromOpaquePtr(TyOrEx);
-    Range = ArgRange;
-    
-    // Verify that the operand is valid.
-    if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof))
-      return ExprError();
-  } else {
-    // Get the end location.
-    Expr *ArgEx = (Expr *)TyOrEx;
-    Range = ArgEx->getSourceRange();
-    ArgTy = ArgEx->getType();
-    
-    // Verify that the operand is valid.
-    bool isInvalid;
-    if (!isSizeof) {
-      isInvalid = CheckAlignOfExpr(ArgEx, OpLoc, Range);
-    } else if (ArgEx->isBitField()) {  // C99 6.5.3.4p1.
-      Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0;
-      isInvalid = true;
-    } else {
-      isInvalid = CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, true);
-    }
-    
-    if (isInvalid) {
-      DeleteExpr(ArgEx);
-      return ExprError();
-    }
-  }
+    QualType ArgTy = QualType::getFromOpaquePtr(TyOrEx);
+    return CreateSizeOfAlignOfExpr(ArgTy, OpLoc, isSizeof, ArgRange);
+  } 
 
-  // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
-  return Owned(new (Context) SizeOfAlignOfExpr(isSizeof, isType, TyOrEx,
-                                               Context.getSizeType(), OpLoc,
-                                               Range.getEnd()));
+  // Get the end location.
+  Expr *ArgEx = (Expr *)TyOrEx;
+  Action::OwningExprResult Result
+    = CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
+
+  if (Result.isInvalid())
+    DeleteExpr(ArgEx);
+
+  return move(Result);
 }
 
 QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {