Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 65459)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -1146,7 +1146,7 @@
 
 /// The UsualUnaryConversions() function is *not* called by this routine.
 /// See C99 6.3.2.1p[2-4] for more details.
-bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, 
+bool Sema::CheckSizeOfAlignOfOperand(QualType exprType,
                                      SourceLocation OpLoc,
                                      const SourceRange &ExprRange,
                                      bool isSizeof) {
@@ -1173,11 +1173,15 @@
 bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
                             const SourceRange &ExprRange) {
   E = E->IgnoreParens();
-  
+
   // alignof decl is always ok. 
   if (isa<DeclRefExpr>(E))
     return false;
-  
+
+  // Cannot know anything else if the expression is dependent.
+  if (E->isTypeDependent())
+    return false;
+
   if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
     if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
       if (FD->isBitField()) {
@@ -1239,6 +1243,9 @@
 }
 
 QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {
+  if (V->isTypeDependent())
+    return Context.DependentTy;
+
   DefaultFunctionArrayConversion(V);
   
   // These operators return the element type of a complex type.
@@ -1491,9 +1498,13 @@
   // and index from the expression types.
   Expr *BaseExpr, *IndexExpr;
   QualType ResultType;
-  if (const PointerType *PTy = LHSTy->getAsPointerType()) {
+  if (LHSTy->isDependentType() || RHSTy->isDependentType()) {
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;
+    ResultType = Context.DependentTy;
+  } else if (const PointerType *PTy = LHSTy->getAsPointerType()) {
+    BaseExpr = LHSExp;
+    IndexExpr = RHSExp;
     // FIXME: need to deal with const...
     ResultType = PTy->getPointeeType();
   } else if (const PointerType *PTy = RHSTy->getAsPointerType()) {
@@ -1513,7 +1524,7 @@
       diag::err_typecheck_subscript_value) << RHSExp->getSourceRange());
   }
   // C99 6.5.2.1p1
-  if (!IndexExpr->getType()->isIntegerType())
+  if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
     return ExprError(Diag(IndexExpr->getLocStart(),
       diag::err_typecheck_subscript) << IndexExpr->getSourceRange());
 
@@ -1521,7 +1532,7 @@
   // the following check catches trying to index a pointer to a function (e.g.
   // void (*)(int)) and pointers to incomplete types.  Functions are not
   // objects in C99.
-  if (!ResultType->isObjectType())
+  if (!ResultType->isObjectType() && !ResultType->isDependentType())
     return ExprError(Diag(BaseExpr->getLocStart(),
                 diag::err_typecheck_subscript_not_object)
       << BaseExpr->getType() << BaseExpr->getSourceRange());
@@ -3429,6 +3440,9 @@
 /// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
 QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc,
                                               bool isInc) {
+  if (Op->isTypeDependent())
+    return Context.DependentTy;
+
   QualType ResType = Op->getType();
   assert(!ResType.isNull() && "no type for increment/decrement expression");
 
@@ -3656,6 +3670,9 @@
 }
 
 QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
+  if (Op->isTypeDependent())
+    return Context.DependentTy;
+
   UsualUnaryConversions(Op);
   QualType Ty = Op->getType();
 
@@ -4107,6 +4124,8 @@
   case UnaryOperator::Minus:
     UsualUnaryConversions(Input);
     resultType = Input->getType();
+    if (resultType->isDependentType())
+      break;
     if (resultType->isArithmeticType()) // C99 6.5.3.3p1
       break;
     else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6-7
@@ -4122,6 +4141,8 @@
   case UnaryOperator::Not: // bitwise complement
     UsualUnaryConversions(Input);
     resultType = Input->getType();
+    if (resultType->isDependentType())
+      break;
     // C99 6.5.3.3p1. We allow complex int and float as a GCC extension.
     if (resultType->isComplexType() || resultType->isComplexIntegerType())
       // C99 does not support '~' for complex conjugation.
@@ -4135,6 +4156,8 @@
     // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
     DefaultFunctionArrayConversion(Input);
     resultType = Input->getType();
+    if (resultType->isDependentType())
+      break;
     if (!resultType->isScalarType()) // C99 6.5.3.3p1
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
         << resultType << Input->getSourceRange());
@@ -4218,10 +4241,12 @@
   QualType ArgTy = QualType::getFromOpaquePtr(argty);
   assert(!ArgTy.isNull() && "Missing type argument!");
 
+  bool Dependent = ArgTy->isDependentType();
+
   // We must have at least one component that refers to the type, and the first
   // one is known to be a field designator.  Verify that the ArgTy represents
   // a struct/union/class.
-  if (!ArgTy->isRecordType())
+  if (!Dependent && !ArgTy->isRecordType())
     return Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy;
 
   // Otherwise, create a compound literal expression as the base, and
@@ -4243,7 +4268,7 @@
     if (OC.isBrackets) {
       // Offset of an array sub-field.  TODO: Should we allow vector elements?
       const ArrayType *AT = Context.getAsArrayType(Res->getType());
-      if (!AT) {
+      if (!AT && !Dependent) {
         Res->Destroy(Context);
         return Diag(OC.LocEnd, diag::err_offsetof_array_type) << Res->getType();
       }
@@ -4252,15 +4277,18 @@
 
       // C99 6.5.2.1p1
       Expr *Idx = static_cast<Expr*>(OC.U.E);
-      if (!Idx->getType()->isIntegerType())
+      if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())
         return Diag(Idx->getLocStart(), diag::err_typecheck_subscript)
           << Idx->getSourceRange();
 
-      Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(),
+      Res = new (Context) ArraySubscriptExpr(Res, Idx,
+                                             Dependent ? Context.DependentTy :
+                                                         AT->getElementType(),
                                              OC.LocEnd);
       continue;
     }
 
+    // FIXME: Dependent type case.
     const RecordType *RC = Res->getType()->getAsRecordType();
     if (!RC) {
       Res->Destroy(Context);
@@ -4311,16 +4339,21 @@
 
   assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
 
-  // The conditional expression is required to be a constant expression.
-  llvm::APSInt condEval(32);
-  SourceLocation ExpLoc;
-  if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc))
-    return Diag(ExpLoc, diag::err_typecheck_choose_expr_requires_constant)
-      << CondExpr->getSourceRange();
+  QualType resType;
+  if (CondExpr->isValueDependent()) {
+    resType = Context.DependentTy;
+  } else {
+    // The conditional expression is required to be a constant expression.
+    llvm::APSInt condEval(32);
+    SourceLocation ExpLoc;
+    if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc))
+      return Diag(ExpLoc, diag::err_typecheck_choose_expr_requires_constant)
+        << CondExpr->getSourceRange();
 
-  // If the condition is > zero, then the AST type is the same as the LSHExpr.
-  QualType resType = condEval.getZExtValue() ? LHSExpr->getType() :
-                                               RHSExpr->getType();
+    // If the condition is > zero, then the AST type is the same as the LSHExpr.
+    resType = condEval.getZExtValue() ? LHSExpr->getType() : RHSExpr->getType();
+  }
+
   return new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
                                   resType, RPLoc);
 }
