[cfe-commits] r80143 - in /cfe/trunk: include/clang/AST/Expr.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-init.cpp
Douglas Gregor
dgregor at apple.com
Wed Aug 26 14:14:46 PDT 2009
Author: dgregor
Date: Wed Aug 26 16:14:46 2009
New Revision: 80143
URL: http://llvm.org/viewvc/llvm-project?rev=80143&view=rev
Log:
Implement support for C++ direct initializers that involve dependent
types or type-dependent expressions.
Added:
cfe/trunk/test/SemaTemplate/instantiate-init.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=80143&r1=80142&r2=80143&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Aug 26 16:14:46 2009
@@ -2443,6 +2443,8 @@
return cast_or_null<Expr>(Exprs[Init]);
}
+ Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
+
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=80143&r1=80142&r2=80143&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Aug 26 16:14:46 2009
@@ -2523,9 +2523,7 @@
return;
}
- // FIXME: Need to handle dependent types and expressions here.
-
- // We will treat direct-initialization as a copy-initialization:
+ // We will represent direct-initialization similarly to copy-initialization:
// int x(1); -as-> int x = 1;
// ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
//
@@ -2535,6 +2533,24 @@
// exactly form was it (like the CodeGen) can handle both cases without
// special case code.
+ // If either the declaration has a dependent type or if any of the expressions
+ // is type-dependent, we represent the initialization via a ParenListExpr for
+ // later use during template instantiation.
+ if (VDecl->getType()->isDependentType() ||
+ Expr::hasAnyTypeDependentArguments((Expr **)Exprs.get(), Exprs.size())) {
+ // Let clients know that initialization was done with a direct initializer.
+ VDecl->setCXXDirectInitializer(true);
+
+ // Store the initialization expressions as a ParenListExpr.
+ unsigned NumExprs = Exprs.size();
+ VDecl->setInit(Context,
+ new (Context) ParenListExpr(Context, LParenLoc,
+ (Expr **)Exprs.release(),
+ NumExprs, RParenLoc));
+ return;
+ }
+
+
// C++ 8.5p11:
// The form of initialization (using parentheses or '=') is generally
// insignificant, but does matter when the entity being initialized has a
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80143&r1=80142&r2=80143&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Aug 26 16:14:46 2009
@@ -15,6 +15,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
+#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
@@ -153,7 +154,31 @@
= SemaRef.SubstExpr(D->getInit(), TemplateArgs);
if (Init.isInvalid())
Var->setInvalidDecl();
- else
+ else if (ParenListExpr *PLE = dyn_cast<ParenListExpr>((Expr *)Init.get())) {
+ // FIXME: We're faking all of the comma locations, which is suboptimal.
+ // Do we even need these comma locations?
+ llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
+ if (PLE->getNumExprs() > 0) {
+ FakeCommaLocs.reserve(PLE->getNumExprs() - 1);
+ for (unsigned I = 0, N = PLE->getNumExprs() - 1; I != N; ++I) {
+ Expr *E = PLE->getExpr(I)->Retain();
+ FakeCommaLocs.push_back(
+ SemaRef.PP.getLocForEndOfToken(E->getLocEnd()));
+ }
+ }
+
+ // Add the direct initializer to the declaration.
+ SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
+ PLE->getLParenLoc(),
+ Sema::MultiExprArg(SemaRef,
+ (void**)PLE->getExprs(),
+ PLE->getNumExprs()),
+ FakeCommaLocs.data(),
+ PLE->getRParenLoc());
+
+ // When Init is destroyed, it will destroy the instantiated ParenListExpr;
+ // we've explicitly retained all of its subexpressions already.
+ } else
SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), move(Init),
D->hasCXXDirectInitializer());
} else if (!Var->isStaticDataMember() || Var->isOutOfLine())
Added: cfe/trunk/test/SemaTemplate/instantiate-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-init.cpp?rev=80143&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-init.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-init.cpp Wed Aug 26 16:14:46 2009
@@ -0,0 +1,28 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+struct X0 { // expected-note 4{{candidate}}
+ X0(int*, float*); // expected-note 4{{candidate}}
+};
+
+template<typename T, typename U>
+X0 f0(T t, U u) {
+ X0 x0(t, u); // expected-error{{no matching}}
+ return X0(t, u); // expected-error{{no matching}}
+}
+
+void test_f0(int *ip, float *fp, double *dp) {
+ f0(ip, fp);
+ f0(ip, dp); // expected-note{{instantiation}}
+}
+
+template<typename Ret, typename T, typename U>
+Ret f1(Ret *retty, T t, U u) {
+ Ret r0(t, u); // expected-error{{no matching}}
+ return Ret(t, u); // expected-error{{no matching}}
+}
+
+void test_f1(X0 *x0, int *ip, float *fp, double *dp) {
+ f1(x0, ip, fp);
+ f1(x0, ip, dp); // expected-note{{instantiation}}
+}
+
More information about the cfe-commits
mailing list