aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo.bagnara@bugseng.com>2012-10-15 21:06:42 +0000
committerAbramo Bagnara <abramo.bagnara@bugseng.com>2012-10-15 21:06:42 +0000
commitb2e80013dbf316f83716a9d9cdc9a6ed5a5a8e2a (patch)
treee01a138d52a2d696a3f7cbdd88075960c21a1c1e
parentac8ea058febf6041871386d135ac2b955ab5d83a (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.cpp28
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.