]> granicus.if.org Git - clang/commitdiff
Template instantiation for the various kinds of AST nodes that occur
authorDouglas Gregor <dgregor@apple.com>
Wed, 20 May 2009 21:38:11 +0000 (21:38 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 20 May 2009 21:38:11 +0000 (21:38 +0000)
due to C++ type construction of the form T(a1, a2, ..., aN).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72183 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/AST/ExprCXX.cpp
lib/Sema/SemaTemplateInstantiateExpr.cpp
test/SemaTemplate/instantiate-expr-4.cpp [new file with mode: 0644]

index f3c82441603c01128d79054afeec050aecaa09a7..df01e9bef4d94dd3acf91c0beb4e7d9e5a0fa060 100644 (file)
@@ -431,8 +431,11 @@ public:
   
   void Destroy(ASTContext &C);
   
-  const VarDecl* getVarDecl() const { return VD; }
-  const CXXConstructorDecl* getConstructor() const { return Constructor; }
+  VarDecl* getVarDecl() const { return VD; }
+  CXXConstructorDecl* getConstructor() const { return Constructor; }
+
+  /// \brief Whether this construction is elidable.
+  bool isElidable() const { return Elidable; }
 
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
@@ -537,7 +540,7 @@ class CXXZeroInitValueExpr : public Expr {
 public:
   CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
                        SourceLocation rParenLoc ) : 
-    Expr(CXXZeroInitValueExprClass, ty),
+    Expr(CXXZeroInitValueExprClass, ty, false, false),
     TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
   
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
@@ -553,6 +556,8 @@ public:
     return SourceRange(TyBeginLoc, RParenLoc);
   }
     
+  CXXZeroInitValueExpr* Clone(ASTContext &C) const;
+
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == CXXZeroInitValueExprClass;
   }
index a73843ca363cad78b012a0fd1c3471fca029738a..cca391e1939178b4a8106a074ca2068265a467a9 100644 (file)
@@ -365,3 +365,7 @@ CXXBoolLiteralExpr* CXXBoolLiteralExpr::Clone(ASTContext &C) const {
 CXXNullPtrLiteralExpr* CXXNullPtrLiteralExpr::Clone(ASTContext &C) const {
   return new (C) CXXNullPtrLiteralExpr(getType(), Loc);
 }
+
+CXXZeroInitValueExpr* CXXZeroInitValueExpr::Clone(ASTContext &C) const {
+  return new (C) CXXZeroInitValueExpr(getType(), TyBeginLoc, RParenLoc);
+}
index 1dad862063cce8c8abe30a03640e3709f6860a4d..1b2fa469575accad095801cf7073c43d79875643 100644 (file)
@@ -85,9 +85,9 @@ namespace {
     // FIXME: CXXTypeIdExpr
     // FIXME: CXXThrowExpr
     // FIXME: CXXDefaultArgExpr
-    // FIXME: CXXConstructExpr
-    // FIXME: CXXFunctionalCastExpr
-    // FIXME: CXXZeroInitValueExpr
+    OwningExprResult VisitCXXConstructExpr(CXXConstructExpr *E);
+    OwningExprResult VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
+    OwningExprResult VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
     // FIXME: CXXNewExpr
     // FIXME: CXXDeleteExpr
     // FIXME: UnaryTypeTraitExpr
@@ -835,6 +835,87 @@ TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
   return SemaRef.Owned(TE);
 }
 
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  assert(!cast<CXXRecordDecl>(E->getConstructor()->getDeclContext())
+           ->isDependentType() && "Dependent constructor shouldn't be here");
+
+  QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
+                                       /*FIXME*/E->getSourceRange().getBegin(),
+                                       DeclarationName());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  bool Invalid = false;
+  llvm::SmallVector<Expr *, 8> Args;
+  for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(), 
+                                   ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg) {
+    OwningExprResult ArgInst = Visit(*Arg);
+    if (ArgInst.isInvalid()) {
+      Invalid = true;
+      break;
+    }
+
+    Args.push_back(ArgInst.takeAs<Expr>());
+  }
+
+
+  VarDecl *Var = 0;
+  if (!Invalid) {
+    Var = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
+                                                        SemaRef.CurContext,
+                                                        TemplateArgs));
+    if (!Var)
+      Invalid = true;
+  }
+
+  if (Invalid) {
+    for (unsigned I = 0, N = Args.size(); I != N; ++I)
+      Args[I]->Destroy(SemaRef.Context);
+
+    return SemaRef.ExprError();
+  }
+
+  return SemaRef.Owned(CXXConstructExpr::Create(SemaRef.Context, Var, T,
+                                                E->getConstructor(), 
+                                                E->isElidable(),
+                                                &Args.front(), Args.size()));
+}
+
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXFunctionalCastExpr(
+                                                   CXXFunctionalCastExpr *E) {
+  // Instantiate the type that we're casting to.
+  QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
+                                                TemplateArgs,
+                                                E->getTypeBeginLoc(),
+                                                DeclarationName());
+  if (ExplicitTy.isNull())
+    return SemaRef.ExprError();
+
+  // Instantiate the subexpression.
+  OwningExprResult SubExpr = Visit(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+  
+  // FIXME: The end of the type's source range is wrong
+  Expr *Sub = SubExpr.takeAs<Expr>();
+  return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()),
+                                           ExplicitTy.getAsOpaquePtr(),
+                                           /*FIXME:*/E->getTypeBeginLoc(),
+                                           Sema::MultiExprArg(SemaRef,
+                                                              (void **)&Sub,
+                                                              1),
+                                           0, 
+                                           E->getRParenLoc());
+}
+
+Sema::OwningExprResult 
+TemplateExprInstantiator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  return SemaRef.Clone(E);
+}
+
 Sema::OwningExprResult 
 TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr(
                                               CXXUnresolvedConstructExpr *E) {
diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp
new file mode 100644 (file)
index 0000000..a5b55b3
--- /dev/null
@@ -0,0 +1,35 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// ---------------------------------------------------------------------
+// C++ Functional Casts
+// ---------------------------------------------------------------------
+template<int N>
+struct ValueInit0 {
+  int f() {
+    return int();
+  }
+};
+
+template struct ValueInit0<5>;
+
+template<int N>
+struct FunctionalCast0 {
+  int f() {
+    return int(N);
+  }
+};
+
+template struct FunctionalCast0<5>;
+
+struct X {
+  X(int, int);
+};
+
+template<int N, int M>
+struct BuildTemporary0 {
+  X f() {
+    return X(N, M);
+  }
+};
+
+template struct BuildTemporary0<5, 7>;