Print template argument names for template class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108916 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 6d7137e..92b44bd 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -16,6 +16,7 @@
#include "CodeGenModule.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/SourceManager.h"
@@ -93,6 +94,40 @@
return llvm::StringRef(StrPtr, NS.length());
}
+/// getClassName - Get class name including template argument list.
+llvm::StringRef
+CGDebugInfo::getClassName(RecordDecl *RD) {
+ ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(RD);
+ if (!Spec)
+ return RD->getName();
+
+ const TemplateArgument *Args;
+ unsigned NumArgs;
+ std::string Buffer;
+ if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
+ const TemplateSpecializationType *TST =
+ cast<TemplateSpecializationType>(TAW->getType());
+ Args = TST->getArgs();
+ NumArgs = TST->getNumArgs();
+ } else {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ Args = TemplateArgs.getFlatArgumentList();
+ NumArgs = TemplateArgs.flat_size();
+ }
+ Buffer = RD->getIdentifier()->getNameStart();
+ PrintingPolicy Policy(CGM.getLangOptions());
+ Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
+ NumArgs,
+ Policy);
+
+ // Copy this name on the side and use its reference.
+ char *StrPtr = DebugInfoNames.Allocate<char>(Buffer.length());
+ memcpy(StrPtr, Buffer.data(), Buffer.length());
+ return llvm::StringRef(StrPtr, Buffer.length());
+
+}
+
/// getOrCreateFile - Get the file debug info descriptor for the input location.
llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
if (!Loc.isValid())
@@ -537,6 +572,18 @@
llvm::DIType ThisPtrType =
DebugFactory.CreateArtificialType(getOrCreateType(ThisPtr, Unit));
+ unsigned Quals = Method->getTypeQualifiers();
+ if (Quals & Qualifiers::Const)
+ ThisPtrType =
+ DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_const_type,
+ Unit, "", Unit,
+ 0, 0, 0, 0, 0, ThisPtrType);
+ if (Quals & Qualifiers::Volatile)
+ ThisPtrType =
+ DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_volatile_type,
+ Unit, "", Unit,
+ 0, 0, 0, 0, 0, ThisPtrType);
+
TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;
Elts.push_back(ThisPtrType);
@@ -831,9 +878,15 @@
llvm::DIDescriptor RDContext =
getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
+
+ llvm::StringRef RDName = RD->getName();
+ // If this is a class, include the template arguments also.
+ if (Tag == llvm::dwarf::DW_TAG_class_type)
+ RDName = getClassName(RD);
+
llvm::DICompositeType RealDecl =
DebugFactory.CreateCompositeType(Tag, RDContext,
- RD->getName(),
+ RDName,
DefUnit, Line, Size, Align, 0, 0,
llvm::DIType(), Elements,
0, ContainingType);
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 620a5f2..fcb2ba0 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -206,6 +206,9 @@
/// is stored on the side.
llvm::StringRef getFunctionName(const FunctionDecl *FD);
+ /// getClassName - Get class name including template argument list.
+ llvm::StringRef getClassName(RecordDecl *RD);
+
/// getVTableName - Get vtable name for the given Class.
llvm::StringRef getVTableName(const CXXRecordDecl *Decl);
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
new file mode 100644
index 0000000..233090c
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm-only -g -S %s -o - | grep "TC<int>"
+template<typename T>
+class TC {
+public:
+ TC(const TC &) {}
+ TC() {}
+};
+
+TC<int> tci;