diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 75b3975322b2..d80db45f4557 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -213,7 +213,8 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) { TemplateArgs.push_back(TemplateArgument(ParamType)); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*Param)) { - Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(), + Expr *E = new (Context) DeclRefExpr(NTTP, + NTTP->getType().getNonReferenceType(), NTTP->getLocation()); TemplateArgs.push_back(TemplateArgument(E)); } else { diff --git a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp new file mode 100644 index 000000000000..ed534a462767 --- /dev/null +++ b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [temp.local]p1: +// Like normal (non-template) classes, class templates have an +// injected-class-name (Clause 9). The injected-class-name can be used with +// or without a template-argument-list. When it is used without +// a template-argument-list, it is equivalent to the injected-class-name +// followed by the template-parameters of the class template enclosed in <>. + +template struct X0 { + X0(); + ~X0(); + X0 f(const X0&); +}; + +// Test non-type template parameters. +template struct X1 { + X1(); + ~X1(); + X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; } +}; + +// When it is used with a template-argument-list, it refers to the specified +// class template specialization, which could be the current specialization +// or another specialization. +// FIXME: Test this clause. + +int i = 42; +int* iptr = &i; +void test() { + X0 x0; (void)x0; + X1<42, i, iptr> x1; (void)x1; +}