summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-11 20:15:17 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-11 20:15:17 +0000
commit6411b92ee6d4ac926a7f5daa2bfd5adfcfa6b033 (patch)
tree05fdd9c13e8892e34615987aeb705f284c745a8d /clang
parent3d22a3af2d3e441fa2b98f3c397804617edb2ef8 (diff)
downloadbcm5719-llvm-6411b92ee6d4ac926a7f5daa2bfd5adfcfa6b033.tar.gz
bcm5719-llvm-6411b92ee6d4ac926a7f5daa2bfd5adfcfa6b033.zip
Tweak the semantics of FunctionDecl::isOutOfLine to consider an
instantiation of a member function template or member function of a class template to be out-of-line if the definition of that function template or member function was defined out-of-line. This ensures that we get the correct linkage for explicit instantiations of out-of-line definitions. llvm-svn: 81562
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Decl.h4
-rw-r--r--clang/include/clang/AST/DeclCXX.h2
-rw-r--r--clang/lib/AST/Decl.cpp24
-rw-r--r--clang/lib/AST/DeclCXX.cpp1
-rw-r--r--clang/test/CodeGenCXX/explicit-instantiation.cpp7
5 files changed, 31 insertions, 7 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index ee3ddb09aac..01276bae1d2 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -1137,6 +1137,10 @@ public:
/// represents.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ /// \brief Determine whether this is or was instantiated from an out-of-line
+ /// definition of a member function.
+ bool isOutOfLine() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 23da3e02837..7fd7ee6a3de 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -757,7 +757,7 @@ public:
return isVirtualAsWritten() ||
(begin_overridden_methods() != end_overridden_methods());
}
-
+
///
void addOverriddenMethod(const CXXMethodDecl *MD);
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8fd6ebf5eec..a7d8216b005 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -704,6 +704,30 @@ FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
Info->setTemplateSpecializationKind(TSK);
}
+bool FunctionDecl::isOutOfLine() const {
+ // FIXME: Should we restrict this to member functions?
+ if (Decl::isOutOfLine())
+ return true;
+
+ // If this function was instantiated from a member function of a
+ // class template, check whether that member function was defined out-of-line.
+ if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) {
+ const FunctionDecl *Definition;
+ if (FD->getBody(Definition))
+ return Definition->isOutOfLine();
+ }
+
+ // If this function was instantiated from a function template,
+ // check whether that function template was defined out-of-line.
+ if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) {
+ const FunctionDecl *Definition;
+ if (FunTmpl->getTemplatedDecl()->getBody(Definition))
+ return Definition->isOutOfLine();
+ }
+
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// TagDecl Implementation
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index e8f97a383d0..073ef947bf8 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -344,7 +344,6 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
isStatic, isInline);
}
-
typedef llvm::DenseMap<const CXXMethodDecl*,
std::vector<const CXXMethodDecl *> *>
OverriddenMethodsMapTy;
diff --git a/clang/test/CodeGenCXX/explicit-instantiation.cpp b/clang/test/CodeGenCXX/explicit-instantiation.cpp
index 33cbf7f872e..8a9e65c4e2e 100644
--- a/clang/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/clang/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,9 +1,6 @@
-// RUN: clang-cc -emit-llvm -femit-all-decls -o %t %s &&
-// RUN: grep "_ZNK4plusIillEclERKiRKl" %t | count 1
+// RUN: clang-cc -emit-llvm -triple i686-pc-linue-gnu -o %t %s &&
+// RUN: grep "define i32 @_ZNK4plusIillEclERKiRKl" %t | count 1
-// FIXME: We should not need the -femit-all-decls, because operator() should
-// be emitted as an external symbol rather than with linkonce_odr linkage.
-// This is a Sema problem.
template<typename T, typename U, typename Result>
struct plus {
Result operator()(const T& t, const U& u) const;
OpenPOWER on IntegriCloud