Uh, embarrassing, of course I failed the attachments:

>From db0bf40e555d033dccff9feea2829b4636307b73 Mon Sep 17 00:00:00 2001
From: Guillaume Papin <[email protected]>
Date: Sun, 28 Apr 2013 13:10:10 +0200
Subject: [PATCH] Add getInlineBody() method to CXXMethodDecl.

---
 include/clang/AST/DeclCXX.h | 14 ++++++++++++++
 lib/AST/DeclCXX.cpp         |  8 ++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index c483dde..4e45f03 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1693,6 +1693,20 @@ public:
 
   bool hasInlineBody() const;
 
+  /// \brief Retrieve the body associated to this method if any.
+  ///
+  /// This function use \c getBody() internally, as such its arguments are the
+  /// same. Unlike \c getBody() this method will also look for template
+  /// instantiations.
+  ///
+  /// \note To check the existence of a body, please use \c hasInlineBody().
+  Stmt *getInlineBody(const FunctionDecl *&Definition) const;
+
+  Stmt *getInlineBody() const {
+    const FunctionDecl *Definition;
+    return getInlineBody(Definition);
+  }
+
   /// \brief Determine whether this is a lambda closure type's static member
   /// function that is used for the result of the lambda's conversion to
   /// function pointer (for a lambda with no captures).
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 0646499..7691833 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1491,6 +1491,14 @@ bool CXXMethodDecl::hasInlineBody() const {
   return CheckFn->hasBody(fn) && !fn->isOutOfLine();
 }
 
+Stmt *CXXMethodDecl::getInlineBody(const FunctionDecl *&Definition) const {
+  const FunctionDecl *FnDecl = getTemplateInstantiationPattern();
+
+  if (!FnDecl)
+    FnDecl = this;
+  return FnDecl->getBody(Definition);
+}
+
 bool CXXMethodDecl::isLambdaStaticInvoker() const {
   return getParent()->isLambda() && 
          getIdentifier() && getIdentifier()->getName() == "__invoke";
-- 
1.8.2.1

>From bdb6be08cba7eea9dc09320a841d2cbac937b33d Mon Sep 17 00:00:00 2001
From: Guillaume Papin <[email protected]>
Date: Sun, 28 Apr 2013 15:00:58 +0200
Subject: [PATCH] cpp11-migrate - AddOverride now look for the body of a
 template instantiation.

- Fixes PR15827 (segfault for extern template instantiations).
- The main file is also checked now.
---
 cpp11-migrate/AddOverride/AddOverrideActions.cpp |  5 ++++-
 test/cpp11-migrate/AddOverride/basic.cpp         | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/cpp11-migrate/AddOverride/AddOverrideActions.cpp b/cpp11-migrate/AddOverride/AddOverrideActions.cpp
index a40f673..0c3532a 100644
--- a/cpp11-migrate/AddOverride/AddOverrideActions.cpp
+++ b/cpp11-migrate/AddOverride/AddOverrideActions.cpp
@@ -32,6 +32,9 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) {
   const CXXMethodDecl *M = Result.Nodes.getDeclAs<CXXMethodDecl>(MethodId);
   assert(M && "Bad Callback. No node provided");
 
+  if (!SM.isFromMainFile(M->getLocStart()))
+    return ;
+
   // First check that there isn't already an override attribute.
   if (!M->hasAttr<OverrideAttr>()) {
     if (M->getLocStart().isFileID()) {
@@ -42,7 +45,7 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) {
         // after that character.
         // FIXME: This transform won't work if there is a comment between
         // the end of the function prototype and the start of the body.
-        StartLoc = M->getBody()->getLocStart();
+        StartLoc = M->getInlineBody()->getLocStart();
         do {
           StartLoc = StartLoc.getLocWithOffset(-1);
         } while (isWhitespace(*FullSourceLoc(StartLoc, SM).getCharacterData()));
diff --git a/test/cpp11-migrate/AddOverride/basic.cpp b/test/cpp11-migrate/AddOverride/basic.cpp
index 1c3616b..8146c25 100644
--- a/test/cpp11-migrate/AddOverride/basic.cpp
+++ b/test/cpp11-migrate/AddOverride/basic.cpp
@@ -108,3 +108,21 @@ public:
   // CHECK: void h() const LLVM_OVERRIDE;
 };
 
+// Test that override is placed correctly if there is a body and the
+// function was instantiated from a template
+template<typename T>
+struct M
+{
+  virtual ~M();
+  virtual T f();
+};
+
+template<typename T>
+struct N : public M<T>
+{
+  virtual T f() { }
+  // CHECK: struct N
+  // CHECK: T f() override { }
+};
+
+extern template class N<char>;
-- 
1.8.2.1

-- 
Guillaume Papin
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to