r215132 - [modules] When emitting an update record containing the body of a destructor,

Richard Smith richard-llvm at metafoo.co.uk
Thu Aug 7 11:53:09 PDT 2014


Author: rsmith
Date: Thu Aug  7 13:53:08 2014
New Revision: 215132

URL: http://llvm.org/viewvc/llvm-project?rev=215132&view=rev
Log:
[modules] When emitting an update record containing the body of a destructor,
also emit the updated 'operator delete' looked up for that destructor. Switch
from UpdateDecl to an actual update record when this happens due to implicitly
defining a special member function and unify this code path and the one for
instantiating a function definition.

Modified:
    cfe/trunk/lib/Serialization/ASTCommon.h
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h
    cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h
    cfe/trunk/test/Modules/cxx-irgen.cpp

Modified: cfe/trunk/lib/Serialization/ASTCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=215132&r1=215131&r2=215132&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.h (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.h Thu Aug  7 13:53:08 2014
@@ -25,8 +25,8 @@ enum DeclUpdateKind {
   UPD_CXX_ADDED_IMPLICIT_MEMBER,
   UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
   UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
+  UPD_CXX_ADDED_FUNCTION_DEFINITION,
   UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
-  UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION,
   UPD_CXX_INSTANTIATED_CLASS_DEFINITION,
   UPD_CXX_RESOLVED_EXCEPTION_SPEC,
   UPD_CXX_DEDUCED_RETURN_TYPE,

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=215132&r1=215131&r2=215132&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Aug  7 13:53:08 2014
@@ -3273,7 +3273,7 @@ void ASTDeclReader::UpdateDecl(Decl *D,
           Reader.ReadSourceLocation(ModuleFile, Record, Idx));
       break;
 
-    case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION: {
+    case UPD_CXX_ADDED_FUNCTION_DEFINITION: {
       FunctionDecl *FD = cast<FunctionDecl>(D);
       if (Reader.PendingBodies[FD]) {
         // FIXME: Maybe check for ODR violations.
@@ -3296,6 +3296,10 @@ void ASTDeclReader::UpdateDecl(Decl *D,
       if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
         std::tie(CD->CtorInitializers, CD->NumCtorInitializers) =
             Reader.ReadCXXCtorInitializers(ModuleFile, Record, Idx);
+      if (auto *DD = dyn_cast<CXXDestructorDecl>(FD))
+        // FIXME: Check consistency.
+        DD->setOperatorDelete(Reader.ReadDeclAs<FunctionDecl>(ModuleFile,
+                                                              Record, Idx));
       // Store the offset of the body so we can lazily load it later.
       Reader.PendingBodies[FD] = GetCurrentCursorOffset();
       HasPendingBody = true;

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=215132&r1=215131&r2=215132&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Aug  7 13:53:08 2014
@@ -4629,17 +4629,17 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
         Record.push_back(GetDeclRef(Update.getDecl()));
         break;
 
-      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
-        AddSourceLocation(Update.getLoc(), Record);
-        break;
-
-      case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION:
+      case UPD_CXX_ADDED_FUNCTION_DEFINITION:
         // An updated body is emitted last, so that the reader doesn't need
         // to skip over the lazy body to reach statements for other records.
         Record.pop_back();
         HasUpdatedBody = true;
         break;
 
+      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
+        AddSourceLocation(Update.getLoc(), Record);
+        break;
+
       case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
         auto *RD = cast<CXXRecordDecl>(D);
         AddUpdatedDeclContext(RD->getPrimaryContext());
@@ -4709,10 +4709,12 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
 
     if (HasUpdatedBody) {
       const FunctionDecl *Def = cast<FunctionDecl>(D);
-      Record.push_back(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION);
+      Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
       Record.push_back(Def->isInlined());
       AddSourceLocation(Def->getInnerLocStart(), Record);
       AddFunctionDefinition(Def, Record);
+      if (auto *DD = dyn_cast<CXXDestructorDecl>(Def))
+        Record.push_back(GetDeclRef(DD->getOperatorDelete()));
     }
 
     OffsetsRecord.push_back(GetDeclRef(D));
@@ -5704,9 +5706,8 @@ void ASTWriter::CompletedImplicitDefinit
   if (!D->isFromASTFile())
     return; // Declaration not imported from PCH.
 
-  // Implicit decl from a PCH was defined.
-  // FIXME: Should implicit definition be a separate FunctionDecl?
-  RewriteDecl(D);
+  // Implicit function decl from a PCH was defined.
+  DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
 }
 
 void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
@@ -5714,10 +5715,8 @@ void ASTWriter::FunctionDefinitionInstan
   if (!D->isFromASTFile())
     return;
 
-  // Since the actual instantiation is delayed, this really means that we need
-  // to update the instantiation location.
   DeclUpdates[D].push_back(
-      DeclUpdate(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION));
+      DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
 }
 
 void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {

Modified: cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h?rev=215132&r1=215131&r2=215132&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h Thu Aug  7 13:53:08 2014
@@ -18,3 +18,9 @@ namespace ImplicitSpecialMembers {
     C c2(c); D d2(d);
   }
 }
+
+namespace OperatorDeleteLookup {
+  // Trigger definition of A::~A() and lookup of operator delete.
+  // Likewise for B<int>::~B().
+  inline void f() { A a; B<int> b; }
+}

Modified: cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h?rev=215132&r1=215131&r2=215132&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h Thu Aug  7 13:53:08 2014
@@ -32,3 +32,9 @@ namespace ImplicitSpecialMembers {
     D(int);
   };
 }
+
+namespace OperatorDeleteLookup {
+  struct A { void operator delete(void*); virtual ~A() = default; };
+  template<typename T> struct B { void operator delete(void*); virtual ~B() {} typedef int t; };
+  typedef B<int>::t b_int_instantated;
+}

Modified: cfe/trunk/test/Modules/cxx-irgen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-irgen.cpp?rev=215132&r1=215131&r2=215132&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-irgen.cpp (original)
+++ cfe/trunk/test/Modules/cxx-irgen.cpp Thu Aug  7 13:53:08 2014
@@ -18,6 +18,9 @@ int b = h();
 // CHECK-DAG: define linkonce_odr {{signext i32|i32}} @_Z3minIiET_S0_S0_(i32
 int c = min(1, 2);
 
+// CHECK-LABEL: define {{.*}} @_ZN20OperatorDeleteLookup1AD0Ev(
+// CHECK: call void @_ZN20OperatorDeleteLookup1AdlEPv(
+
 namespace ImplicitSpecialMembers {
   // CHECK-LABEL: define {{.*}} @_ZN22ImplicitSpecialMembers1DC2EOS0_(
   // CHECK: call {{.*}} @_ZN22ImplicitSpecialMembers1AC1ERKS0_(
@@ -45,6 +48,12 @@ namespace ImplicitSpecialMembers {
   D d3(static_cast<D&&>(d1));
 }
 
+namespace OperatorDeleteLookup {
+  // Trigger emission of B's vtable and deleting dtor.
+  // This requires us to know what operator delete was selected.
+  void g() { f(); }
+}
+
 // CHECK: define available_externally {{signext i32|i32}} @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align
 
 // CHECK: attributes #[[ALWAYS_INLINE]] = {{.*}} alwaysinline





More information about the cfe-commits mailing list