[cfe-commits] r97560 - /cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Douglas Gregor dgregor at apple.com
Mon Mar 1 23:38:39 PST 2010


Author: dgregor
Date: Tue Mar  2 01:38:39 2010
New Revision: 97560

URL: http://llvm.org/viewvc/llvm-project?rev=97560&view=rev
Log:
Unify initializer-instantiation code for variable declarations and
base/member initializers.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=97560&r1=97559&r2=97560&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Mar  2 01:38:39 2010
@@ -202,6 +202,72 @@
   return false;
 }
 
+/// \brief Instantiate an initializer, breaking it into separate
+/// initialization arguments.
+///
+/// \param S The semantic analysis object.
+///
+/// \param Init The initializer to instantiate.
+///
+/// \param TemplateArgs Template arguments to be substituted into the
+/// initializer.
+///
+/// \param NewArgs Will be filled in with the instantiation arguments.
+///
+/// \returns true if an error occurred, false otherwise
+static bool InstantiateInitializer(Sema &S, Expr *Init,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                                   SourceLocation &LParenLoc,
+                               llvm::SmallVector<SourceLocation, 4> &CommaLocs,
+                             ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
+                                   SourceLocation &RParenLoc) {
+  NewArgs.clear();
+  LParenLoc = SourceLocation();
+  RParenLoc = SourceLocation();
+
+  if (!Init)
+    return false;
+
+  if (CXXExprWithTemporaries *ExprTemp = dyn_cast<CXXExprWithTemporaries>(Init))
+    Init = ExprTemp->getSubExpr();
+
+  while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
+    Init = Binder->getSubExpr();
+
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
+    Init = ICE->getSubExprAsWritten();
+
+  if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    LParenLoc = ParenList->getLParenLoc();
+    RParenLoc = ParenList->getRParenLoc();
+    return InstantiateInitializationArguments(S, ParenList->getExprs(),
+                                              ParenList->getNumExprs(),
+                                              TemplateArgs, CommaLocs, 
+                                              NewArgs);
+  }
+
+  if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {
+    if (InstantiateInitializationArguments(S,
+                                           Construct->getArgs(),
+                                           Construct->getNumArgs(),
+                                           TemplateArgs,
+                                           CommaLocs, NewArgs))
+      return true;
+
+    // FIXME: Fake locations!
+    LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart());
+    RParenLoc = CommaLocs.empty()? LParenLoc : CommaLocs.back();
+    return false;
+  }
+ 
+  Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
+  if (Result.isInvalid())
+    return true;
+
+  NewArgs.push_back(Result.takeAs<Expr>());
+  return false;
+}
+
 Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
   // Do substitution on the type of the declaration
   TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
@@ -259,77 +325,33 @@
     else
       SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
 
-    // Extract the initializer, skipping through any temporary-binding 
-    // expressions and look at the subexpression as it was written.
-    Expr *DInit = D->getInit();
-    if (CXXExprWithTemporaries *ExprTemp
-          = dyn_cast<CXXExprWithTemporaries>(DInit))
-      DInit = ExprTemp->getSubExpr();
-    while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(DInit))
-      DInit = Binder->getSubExpr();
-    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(DInit))
-      DInit = ICE->getSubExprAsWritten();
-        
-    if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(DInit)) {
-      // The initializer is a parenthesized list of expressions that is
-      // type-dependent. Instantiate each of the expressions; we'll be 
-      // performing direct initialization with them.
-      llvm::SmallVector<SourceLocation, 4> CommaLocs;
-      ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
-      if (!InstantiateInitializationArguments(SemaRef, 
-                                              PLE->getExprs(), 
-                                              PLE->getNumExprs(),
-                                              TemplateArgs,
-                                              CommaLocs, InitArgs)) {
+    // Instantiate the initializer.
+    SourceLocation LParenLoc, RParenLoc;
+    llvm::SmallVector<SourceLocation, 4> CommaLocs;
+    ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
+    if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
+                                CommaLocs, InitArgs, RParenLoc)) {
+      // Attach the initializer to the declaration.
+      if (D->hasCXXDirectInitializer()) {
         // Add the direct initializer to the declaration.
         SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
-                                              PLE->getLParenLoc(),
+                                              LParenLoc,
                                               move_arg(InitArgs),
                                               CommaLocs.data(),
-                                              PLE->getRParenLoc());
+                                              RParenLoc);
+      } else if (InitArgs.size() == 1) {
+        Expr *Init = (Expr*)(InitArgs.take()[0]);
+        SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), 
+                                     SemaRef.Owned(Init),
+                                     false);        
+      } else {
+        assert(InitArgs.size() == 0);
+        SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);    
       }
-    } else if (CXXConstructExpr *Construct =dyn_cast<CXXConstructExpr>(DInit)) {
-      // The initializer resolved to a constructor. Instantiate the constructor
-      // arguments.
-      llvm::SmallVector<SourceLocation, 4> CommaLocs;
-      ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
-      
-      if (!InstantiateInitializationArguments(SemaRef, 
-                                              Construct->getArgs(),
-                                              Construct->getNumArgs(),
-                                              TemplateArgs,
-                                              CommaLocs, InitArgs)) {
-        if (D->hasCXXDirectInitializer()) {
-          SourceLocation FakeLParenLoc = 
-            SemaRef.PP.getLocForEndOfToken(D->getLocation());
-          SourceLocation FakeRParenLoc = CommaLocs.empty()? FakeLParenLoc
-                                                          : CommaLocs.back();
-          SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
-                                                FakeLParenLoc,
-                                                move_arg(InitArgs),
-                                                CommaLocs.data(),
-                                                FakeRParenLoc);          
-        } else if (InitArgs.size() == 1) {
-          Expr *Init = (Expr*)(InitArgs.take()[0]);
-          SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), 
-                                       SemaRef.Owned(Init),
-                                       false);
-        } else {
-          assert(InitArgs.size() == 0);
-          SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);          
-        }
-      } 
     } else {
-      OwningExprResult Init
-        = SemaRef.SubstExpr(D->getInit(), TemplateArgs);
-
-      // FIXME: Not happy about invalidating decls just because of a bad 
-      // initializer, unless it affects the type.
-      if (Init.isInvalid())
-        Var->setInvalidDecl();
-      else
-        SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), move(Init),
-                                     D->hasCXXDirectInitializer());
+      // FIXME: Not too happy about invalidating the declaration
+      // because of a bogus initializer.
+      Var->setInvalidDecl();
     }
     
     SemaRef.PopExpressionEvaluationContext();
@@ -1888,29 +1910,15 @@
        Inits != InitsEnd; ++Inits) {
     CXXBaseOrMemberInitializer *Init = *Inits;
 
+    SourceLocation LParenLoc, RParenLoc;
     ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
     llvm::SmallVector<SourceLocation, 4> CommaLocs;
 
-    // Instantiate all the arguments.
-    Expr *InitE = Init->getInit();
-    if (!InitE) {
-      // Nothing to instantiate;
-    } else if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(InitE)) {
-      if (InstantiateInitializationArguments(*this, ParenList->getExprs(),
-                                             ParenList->getNumExprs(),
-                                             TemplateArgs, CommaLocs, 
-                                             NewArgs)) {
-        AnyErrors = true;
-        continue;
-      }
-    } else {
-      OwningExprResult InitArg = SubstExpr(InitE, TemplateArgs);
-      if (InitArg.isInvalid()) {
-        AnyErrors = true;
-        continue;
-      }
-      
-      NewArgs.push_back(InitArg.release());
+    // Instantiate the initializer.
+    if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, 
+                               LParenLoc, CommaLocs, NewArgs, RParenLoc)) {
+      AnyErrors = true;
+      continue;
     }
     
     MemInitResult NewInit;





More information about the cfe-commits mailing list