[cfe-commits] [PATCH (need approval) 2/2] Compute a more accurate SourceRange for out-of-line template declarations

Peter Collingbourne peter at pcc.me.uk
Mon Jul 5 11:42:35 PDT 2010


Now that DeclaratorDecl and TagDecl store out-of-line template
declaration information, we can compute a more accurate SourceRange
that covers outer template declarations.  This patch teaches
DeclaratorDecl and TagDecl subclasses' getSourceRange() methods to
check for and use out-of-line template declaration information.
---
 include/clang/AST/Decl.h         |   21 ++++++++++++++++++++-
 include/clang/AST/DeclTemplate.h |    2 ++
 lib/AST/Decl.cpp                 |   29 ++++++++++++++++++++++++-----
 3 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index c35a399..213df60 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -436,6 +436,17 @@ public:
       DeclInfo = TI;
   }
 
+  /// getInnerLocStart - Return SourceLocation representing start of source
+  /// range ignoring outer template declarations.
+  virtual SourceLocation getInnerLocStart() const { return getLocation(); }
+
+  /// getOuterLocStart - Return SourceLocation representing start of source
+  /// range taking into account any outer template declarations.
+  SourceLocation getOuterLocStart() const;
+  SourceRange getSourceRange() const {
+    return SourceRange(getOuterLocStart(), getLocation());
+  }
+
   NestedNameSpecifier *getQualifier() const {
     return hasExtInfo() ? getExtInfo()->NNS : 0;
   }
@@ -601,6 +612,7 @@ public:
   virtual void Destroy(ASTContext& C);
   virtual ~VarDecl();
 
+  virtual SourceLocation getInnerLocStart() const;
   virtual SourceRange getSourceRange() const;
 
   StorageClass getStorageClass() const { return (StorageClass)SClass; }
@@ -1209,7 +1221,7 @@ public:
                                     bool Qualified) const;
 
   virtual SourceRange getSourceRange() const {
-    return SourceRange(getLocation(), EndRangeLoc);
+    return SourceRange(getOuterLocStart(), EndRangeLoc);
   }
   void setLocEnd(SourceLocation E) {
     EndRangeLoc = E;
@@ -1854,6 +1866,13 @@ public:
   SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
   void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
 
+  /// getInnerLocStart - Return SourceLocation representing start of source
+  /// range ignoring outer template declarations.
+  virtual SourceLocation getInnerLocStart() const { return TagKeywordLoc; }
+
+  /// getOuterLocStart - Return SourceLocation representing start of source
+  /// range taking into account any outer template declarations.
+  SourceLocation getOuterLocStart() const;
   virtual SourceRange getSourceRange() const;
 
   virtual TagDecl* getCanonicalDecl();
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 84e7553..31edc43 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -1145,6 +1145,8 @@ public:
     return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
   }
 
+  SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
+
   void Profile(llvm::FoldingSetNodeID &ID) const {
     Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
             getASTContext());
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c3c30f9..fcf4e13 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -523,6 +523,14 @@ bool NamedDecl::isCXXInstanceMember() const {
 // DeclaratorDecl Implementation
 //===----------------------------------------------------------------------===//
 
+template <typename DeclT>
+static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) {
+  if (decl->getNumTemplateParameterLists() > 0)
+    return decl->getTemplateParameterList(0)->getTemplateLoc();
+  else
+    return decl->getInnerLocStart();
+}
+
 DeclaratorDecl::~DeclaratorDecl() {}
 void DeclaratorDecl::Destroy(ASTContext &C) {
   if (hasExtInfo())
@@ -566,6 +574,10 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
   }
 }
 
+SourceLocation DeclaratorDecl::getOuterLocStart() const {
+  return getTemplateOrInnerLocStart(this);
+}
+
 void
 QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
                                              unsigned NumTPLists,
@@ -636,14 +648,17 @@ void VarDecl::Destroy(ASTContext& C) {
 VarDecl::~VarDecl() {
 }
 
-SourceRange VarDecl::getSourceRange() const {
+SourceLocation VarDecl::getInnerLocStart() const {
   SourceLocation Start = getTypeSpecStartLoc();
   if (Start.isInvalid())
     Start = getLocation();
-  
+  return Start;
+}
+
+SourceRange VarDecl::getSourceRange() const {
   if (getInit())
-    return SourceRange(Start, getInit()->getLocEnd());
-  return SourceRange(Start, getLocation());
+    return SourceRange(getOuterLocStart(), getInit()->getLocEnd());
+  return SourceRange(getOuterLocStart(), getLocation());
 }
 
 bool VarDecl::isExternC() const {
@@ -1541,9 +1556,13 @@ void TagDecl::Destroy(ASTContext &C) {
   TypeDecl::Destroy(C);
 }
 
+SourceLocation TagDecl::getOuterLocStart() const {
+  return getTemplateOrInnerLocStart(this);
+}
+
 SourceRange TagDecl::getSourceRange() const {
   SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
-  return SourceRange(TagKeywordLoc, E);
+  return SourceRange(getOuterLocStart(), E);
 }
 
 TagDecl* TagDecl::getCanonicalDecl() {
-- 
1.6.5




More information about the cfe-commits mailing list