Template instantiation for C99 designated initializers, because we
can. Also, delay semantic analysis of initialization for
value-dependent as well as type-dependent expressions, since we can't
always properly type-check a value-dependent expression.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72233 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index f3ad2a1..126b386 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -117,7 +117,8 @@
                                  SourceLocation InitLoc,
                                  DeclarationName InitEntity,
                                  bool DirectInit) {
-  if (DeclType->isDependentType() || Init->isTypeDependent())
+  if (DeclType->isDependentType() || 
+      Init->isTypeDependent() || Init->isValueDependent())
     return false;
   
   // C++ [dcl.init.ref]p1:
@@ -1635,7 +1636,9 @@
     case Designator::ArrayDesignator: {
       Expr *Index = static_cast<Expr *>(D.getArrayIndex());
       llvm::APSInt IndexValue;
-      if (CheckArrayDesignatorExpr(*this, Index, IndexValue))
+      if (!Index->isTypeDependent() &&
+          !Index->isValueDependent() &&
+          CheckArrayDesignatorExpr(*this, Index, IndexValue))
         Invalid = true;
       else {
         Designators.push_back(ASTDesignator(InitExpressions.size(),
@@ -1651,12 +1654,20 @@
       Expr *EndIndex = static_cast<Expr *>(D.getArrayRangeEnd());
       llvm::APSInt StartValue;
       llvm::APSInt EndValue;
-      if (CheckArrayDesignatorExpr(*this, StartIndex, StartValue) ||
-          CheckArrayDesignatorExpr(*this, EndIndex, EndValue))
+      bool StartDependent = StartIndex->isTypeDependent() ||
+                            StartIndex->isValueDependent();
+      bool EndDependent = EndIndex->isTypeDependent() ||
+                          EndIndex->isValueDependent();
+      if ((!StartDependent &&
+           CheckArrayDesignatorExpr(*this, StartIndex, StartValue)) ||
+          (!EndDependent &&
+           CheckArrayDesignatorExpr(*this, EndIndex, EndValue)))
         Invalid = true;
       else {
         // Make sure we're comparing values with the same bit width.
-        if (StartValue.getBitWidth() > EndValue.getBitWidth())
+        if (StartDependent || EndDependent) {
+          // Nothing to compute.
+        } else if (StartValue.getBitWidth() > EndValue.getBitWidth())
           EndValue.extend(StartValue.getBitWidth());
         else if (StartValue.getBitWidth() < EndValue.getBitWidth())
           StartValue.extend(EndValue.getBitWidth());
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 283b0d3..38f9245 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -16,6 +16,7 @@
 #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;
@@ -61,8 +62,8 @@
     OwningExprResult VisitChooseExpr(ChooseExpr *E);
     OwningExprResult VisitVAArgExpr(VAArgExpr *E);
     OwningExprResult VisitInitListExpr(InitListExpr *E);
-    // FIXME: DesignatedInitExpr
-    // FIXME: ImplicitValueInitExpr
+    OwningExprResult VisitDesignatedInitExpr(DesignatedInitExpr *E);
+    OwningExprResult VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
     // FIXME: ExtVectorElementExpr
     // FIXME: BlockExpr
     // FIXME: BlockDeclRefExpr
@@ -595,6 +596,62 @@
 }
 
 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.
+  ExprVector ArrayExprs(SemaRef); // Expresses used in array designators
+  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(false && "No array range designators, yet");
+  }
+
+  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::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
   bool isSizeOf = E->isSizeOf();