diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-11 20:15:17 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-11 20:15:17 +0000 |
commit | 6411b92ee6d4ac926a7f5daa2bfd5adfcfa6b033 (patch) | |
tree | 05fdd9c13e8892e34615987aeb705f284c745a8d /clang | |
parent | 3d22a3af2d3e441fa2b98f3c397804617edb2ef8 (diff) | |
download | bcm5719-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.h | 4 | ||||
-rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 2 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 24 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 1 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/explicit-instantiation.cpp | 7 |
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; |