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