diff options
author | Abramo Bagnara <abramo.bagnara@bugseng.com> | 2012-10-15 21:06:42 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@bugseng.com> | 2012-10-15 21:06:42 +0000 |
commit | b2e80013dbf316f83716a9d9cdc9a6ed5a5a8e2a (patch) | |
tree | e01a138d52a2d696a3f7cbdd88075960c21a1c1e | |
parent | ac8ea058febf6041871386d135ac2b955ab5d83a (diff) |
Fixed ClassTemplateSpecializationDecl source range.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165975 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index fc31d2f55b..a70983f4c9 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -764,13 +764,27 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const { SourceRange ClassTemplateSpecializationDecl::getSourceRange() const { if (ExplicitInfo) { - SourceLocation Begin = getExternLoc(); - if (Begin.isInvalid()) - Begin = getTemplateKeywordLoc(); - SourceLocation End = getRBraceLoc(); - if (End.isInvalid()) - End = getTypeAsWritten()->getTypeLoc().getEndLoc(); - return SourceRange(Begin, End); + SourceLocation Begin = getTemplateKeywordLoc(); + if (Begin.isValid()) { + // Here we have an explicit (partial) specialization or instantiation. + assert(getSpecializationKind() == TSK_ExplicitSpecialization || + getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || + getSpecializationKind() == TSK_ExplicitInstantiationDefinition); + if (getExternLoc().isValid()) + Begin = getExternLoc(); + SourceLocation End = getRBraceLoc(); + if (End.isInvalid()) + End = getTypeAsWritten()->getTypeLoc().getEndLoc(); + return SourceRange(Begin, End); + } + // An implicit instantiation of a class template partial specialization + // uses ExplicitInfo to record the TypeAsWritten, but the source + // locations should be retrieved from the instantiation pattern. + typedef ClassTemplatePartialSpecializationDecl CTPSDecl; + CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this)); + CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); + assert(inst_from != 0); + return inst_from->getSourceRange(); } else { // No explicit info available. |