[cfe-commits] r81562 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclCXX.h lib/AST/Decl.cpp lib/AST/DeclCXX.cpp test/CodeGenCXX/explicit-instantiation.cpp

Douglas Gregor dgregor at apple.com
Fri Sep 11 13:15:17 PDT 2009


Author: dgregor
Date: Fri Sep 11 15:15:17 2009
New Revision: 81562

URL: http://llvm.org/viewvc/llvm-project?rev=81562&view=rev
Log:
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. 


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/test/CodeGenCXX/explicit-instantiation.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=81562&r1=81561&r2=81562&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Sep 11 15:15:17 2009
@@ -1137,6 +1137,10 @@
   /// 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;

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=81562&r1=81561&r2=81562&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Sep 11 15:15:17 2009
@@ -757,7 +757,7 @@
     return isVirtualAsWritten() ||
       (begin_overridden_methods() != end_overridden_methods());
   }
-
+  
   ///
   void addOverriddenMethod(const CXXMethodDecl *MD);
 

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=81562&r1=81561&r2=81562&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Sep 11 15:15:17 2009
@@ -704,6 +704,30 @@
   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
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=81562&r1=81561&r2=81562&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Sep 11 15:15:17 2009
@@ -344,7 +344,6 @@
                                isStatic, isInline);
 }
 
-
 typedef llvm::DenseMap<const CXXMethodDecl*,
                        std::vector<const CXXMethodDecl *> *>
                        OverriddenMethodsMapTy;

Modified: cfe/trunk/test/CodeGenCXX/explicit-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/explicit-instantiation.cpp?rev=81562&r1=81561&r2=81562&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/explicit-instantiation.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/explicit-instantiation.cpp Fri Sep 11 15:15:17 2009
@@ -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;





More information about the cfe-commits mailing list