Index: lib/AST/TemplateBase.cpp =================================================================== --- lib/AST/TemplateBase.cpp +++ lib/AST/TemplateBase.cpp @@ -392,9 +392,22 @@ case Declaration: { NamedDecl *ND = cast(getAsDecl()); - Out << '&'; + bool needsRef = true; + if (auto VD = dyn_cast(ND)) { + const clang::Type *ArgTy = VD->getType()->getUnqualifiedDesugaredType(); + const clang::Type *ParmTy + = getParamTypeForDecl()->getUnqualifiedDesugaredType(); + clang::ASTContext& Ctx = ND->getASTContext(); + needsRef = !Ctx.hasSameType(ArgTy, ParmTy); + if (needsRef && (ArgTy->isArrayType() || ArgTy->isFunctionType())) { + const clang::Type *decayedArgTy + = Ctx.getDecayedType(clang::QualType(ArgTy, 0)).getTypePtr(); + needsRef = !Ctx.hasSameType(decayedArgTy, ParmTy); + } + } + if (needsRef) + Out << '&'; if (ND->getDeclName()) { - // FIXME: distinguish between pointer and reference args? ND->printQualifiedName(Out); } else { Out << "(anonymous)"; Index: test/CodeGenCXX/debug-info-codeview-display-name.cpp =================================================================== --- test/CodeGenCXX/debug-info-codeview-display-name.cpp +++ test/CodeGenCXX/debug-info-codeview-display-name.cpp @@ -90,4 +90,4 @@ void fn_tmpl() {} template void fn_tmpl(); -// CHECK-DAG: "fn_tmpl" +// CHECK-DAG: "fn_tmpl" Index: test/CodeGenCXX/debug-info-template.cpp =================================================================== --- test/CodeGenCXX/debug-info-template.cpp +++ test/CodeGenCXX/debug-info-template.cpp @@ -1,6 +1,6 @@ // RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s -// CHECK: @tci = global %"struct.TC::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]] +// CHECK: @tci = global %"struct.TC::nested" zeroinitializer, align 1, !dbg [[TCI:![0-9]+]] // CHECK: @tcn = global %struct.TC zeroinitializer, align 1, !dbg [[TCN:![0-9]+]] // CHECK: @nn = global %struct.NN zeroinitializer, align 1, !dbg [[NN:![0-9]+]] @@ -31,7 +31,7 @@ // CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested", // CHECK-SAME: scope: ![[TC:[0-9]+]], -// CHECK: ![[TC]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TC" +// CHECK: ![[TC]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TC" // CHECK-SAME: templateParams: [[TCARGS:![0-9]*]] TC // CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]} Index: test/SemaTemplate/temp_arg_nontype_cxx11.cpp =================================================================== --- test/SemaTemplate/temp_arg_nontype_cxx11.cpp +++ test/SemaTemplate/temp_arg_nontype_cxx11.cpp @@ -36,3 +36,22 @@ struct Y { constexpr operator int() const { return 0; } }; template struct A {}; // expected-error {{cannot be deduced}} expected-note {{'y'}} } + +using FourChars = const char[4]; +constexpr FourChars kEta = "Eta"; +constexpr const char* kNull = "Phi"; + +template class Column {}; +template class Dolumn {}; +template class Folumn {}; +template class Golumn {}; +template class Holumn {}; + +void lookup() { + Column().ls(); // expected-error {{().ls(); // expected-error {{().ls(); // expected-error {{().ls(); // expected-error {{<&kEta,}} + Golumn<&kEta, double>().ls(); // expected-error {{<&kEta,}} + Holumn<&kNull, double>().ls(); // expected-error {{<&kNull,}} +}