r230830 - Rework our handling of key functions. We used to track a complete list of all

Richard Smith richard-llvm at metafoo.co.uk
Fri Feb 27 17:01:57 PST 2015


Author: rsmith
Date: Fri Feb 27 19:01:56 2015
New Revision: 230830

URL: http://llvm.org/viewvc/llvm-project?rev=230830&view=rev
Log:
Rework our handling of key functions. We used to track a complete list of all
dynamic classes in the translation unit and check whether each one's key
function is defined when we got to the end of the TU (and when we got to the
end of each module). This is really terrible for modules performance, since it
causes unnecessary deserialization of every dynamic class in every compilation.

We now use a much simpler (and, in a modules build, vastly more efficient)
system: when we see an out-of-line definition of a virtual function, we check
whether that function was in fact its class's key function. (If so, we need to
emit the vtable.)

Modified:
    cfe/trunk/include/clang/Sema/ExternalSemaSource.h
    cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/CodeGenCXX/arm64.cpp
    cfe/trunk/test/CodeGenCXX/cxx11-vtable-key-function.cpp
    cfe/trunk/test/CodeGenCXX/key-function-vtable.cpp

Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Fri Feb 27 19:01:56 2015
@@ -128,14 +128,6 @@ public:
   /// introduce the same declarations repeatedly.
   virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {}
 
-  /// \brief Read the set of dynamic classes known to the external Sema source.
-  ///
-  /// The external source should append its own dynamic classes to
-  /// the given vector of declarations. Note that this routine may be
-  /// invoked multiple times; the external source should take care not to
-  /// introduce the same declarations repeatedly.
-  virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {}
-
   /// \brief Read the set of potentially unused typedefs known to the source.
   ///
   /// The external source should append its own potentially unused local

Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Fri Feb 27 19:01:56 2015
@@ -274,14 +274,6 @@ public:
   /// introduce the same declarations repeatedly.
   void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override;
 
-  /// \brief Read the set of dynamic classes known to the external Sema source.
-  ///
-  /// The external source should append its own dynamic classes to
-  /// the given vector of declarations. Note that this routine may be
-  /// invoked multiple times; the external source should take care not to
-  /// introduce the same declarations repeatedly.
-  void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override;
-
   /// \brief Read the set of potentially unused typedefs known to the source.
   ///
   /// The external source should append its own potentially unused local

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 27 19:01:56 2015
@@ -5059,14 +5059,6 @@ public:
   /// \brief Load any externally-stored vtable uses.
   void LoadExternalVTableUses();
 
-  typedef LazyVector<CXXRecordDecl *, ExternalSemaSource,
-                     &ExternalSemaSource::ReadDynamicClasses, 2, 2>
-    DynamicClassesType;
-
-  /// \brief A list of all of the dynamic classes in this translation
-  /// unit.
-  DynamicClassesType DynamicClasses;
-
   /// \brief Note that the vtable for the given class was used at the
   /// given location.
   void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Feb 27 19:01:56 2015
@@ -425,8 +425,7 @@ namespace clang {
       /// \brief Record code for the array of VTable uses.
       VTABLE_USES = 19,
 
-      /// \brief Record code for the array of dynamic classes.
-      DYNAMIC_CLASSES = 20,
+      // ID 20 used to be for a list of dynamic classes.
 
       /// \brief Record code for referenced selector pool.
       REFERENCED_SELECTOR_POOL = 21,

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Feb 27 19:01:56 2015
@@ -776,12 +776,6 @@ private:
   /// local extern "C" declarations.
   SmallVector<uint64_t, 16> LocallyScopedExternCDecls;
 
-  /// \brief The IDs of all dynamic class declarations in the chain.
-  ///
-  /// Sema tracks these because it checks for the key functions being defined
-  /// at the end of the TU, in which case it directs CodeGen to emit the VTable.
-  SmallVector<uint64_t, 16> DynamicClasses;
-
   /// \brief The IDs of all potentially unused typedef names in the chain.
   ///
   /// Sema tracks these to emit warnings.
@@ -1818,8 +1812,6 @@ public:
 
   void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override;
 
-  void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) override;
-
   void ReadUnusedLocalTypedefNameCandidates(
       llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override;
 

Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Fri Feb 27 19:01:56 2015
@@ -236,12 +236,6 @@ void MultiplexExternalSemaSource::ReadEx
     Sources[i]->ReadExtVectorDecls(Decls);
 }
 
-void MultiplexExternalSemaSource::ReadDynamicClasses(
-                                       SmallVectorImpl<CXXRecordDecl*> &Decls) {
-  for(size_t i = 0; i < Sources.size(); ++i)
-    Sources[i]->ReadDynamicClasses(Decls);
-}
-
 void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates(
     llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
   for(size_t i = 0; i < Sources.size(); ++i)

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Fri Feb 27 19:01:56 2015
@@ -621,22 +621,6 @@ void Sema::ActOnEndOfTranslationUnit() {
   if (TUKind != TU_Prefix) {
     DiagnoseUseOfUnimplementedSelectors();
 
-    // If any dynamic classes have their key function defined within
-    // this translation unit, then those vtables are considered "used" and must
-    // be emitted.
-    for (DynamicClassesType::iterator I = DynamicClasses.begin(ExternalSource),
-                                      E = DynamicClasses.end();
-         I != E; ++I) {
-      assert(!(*I)->isDependentType() &&
-             "Should not see dependent types here!");
-      if (const CXXMethodDecl *KeyFunction =
-              Context.getCurrentKeyFunction(*I)) {
-        const FunctionDecl *Definition = nullptr;
-        if (KeyFunction->hasBody(Definition))
-          MarkVTableUsed(Definition->getLocation(), *I, true);
-      }
-    }
-
     // If DefinedUsedVTables ends up marking any virtual member functions it
     // might lead to more pending template instantiations, which we then need
     // to instantiate.
@@ -668,6 +652,8 @@ void Sema::ActOnEndOfTranslationUnit() {
 
   // All delayed member exception specs should be checked or we end up accepting
   // incompatible declarations.
+  // FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to
+  // write out the lists to the AST file (if any).
   assert(DelayedDefaultedMemberExceptionSpecs.empty());
   assert(DelayedExceptionSpecChecks.empty());
 

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Feb 27 19:01:56 2015
@@ -8011,28 +8011,8 @@ bool Sema::CheckFunctionDeclaration(Scop
       // This needs to happen first so that 'inline' propagates.
       NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
 
-      if (isa<CXXMethodDecl>(NewFD)) {
-        // A valid redeclaration of a C++ method must be out-of-line,
-        // but (unfortunately) it's not necessarily a definition
-        // because of templates, which means that the previous
-        // declaration is not necessarily from the class definition.
-
-        // For just setting the access, that doesn't matter.
-        CXXMethodDecl *oldMethod = cast<CXXMethodDecl>(OldDecl);
-        NewFD->setAccess(oldMethod->getAccess());
-
-        // Update the key-function state if necessary for this ABI.
-        if (NewFD->isInlined() &&
-            !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
-          // setNonKeyFunction needs to work with the original
-          // declaration from the class definition, and isVirtual() is
-          // just faster in that case, so map back to that now.
-          oldMethod = cast<CXXMethodDecl>(oldMethod->getFirstDecl());
-          if (oldMethod->isVirtual()) {
-            Context.setNonKeyFunction(oldMethod);
-          }
-        }
-      }
+      if (isa<CXXMethodDecl>(NewFD))
+        NewFD->setAccess(OldDecl->getAccess());
     }
   }
 
@@ -10559,7 +10539,31 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
           !FD->isDependentContext())
         computeNRVO(Body, getCurFunction());
     }
-    
+
+    if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      const CXXMethodDecl *KeyFunction;
+      if (MD->isOutOfLine() && (MD = MD->getCanonicalDecl()) &&
+          MD->isVirtual() &&
+          (KeyFunction = Context.getCurrentKeyFunction(MD->getParent())) &&
+          MD == KeyFunction->getCanonicalDecl()) {
+        // Update the key-function state if necessary for this ABI.
+        if (FD->isInlined() &&
+            !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
+          Context.setNonKeyFunction(MD);
+
+          // If the newly-chosen key function is already defined, then we
+          // need to mark the vtable as used retroactively.
+          KeyFunction = Context.getCurrentKeyFunction(MD->getParent());
+          const FunctionDecl *Definition;
+          if (KeyFunction && KeyFunction->isDefined(Definition))
+            MarkVTableUsed(Definition->getLocation(), MD->getParent(), true);
+        } else {
+          // We just defined they key function; mark the vtable as used.
+          MarkVTableUsed(FD->getLocation(), MD->getParent(), true);
+        }
+      }
+    }
+
     assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
            "Function parsing confused");
   } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Feb 27 19:01:56 2015
@@ -4875,9 +4875,6 @@ void Sema::CheckCompletedCXXClass(CXXRec
     }
   }
 
-  if (Record->isDynamicClass() && !Record->isDependentType())
-    DynamicClasses.push_back(Record);
-
   if (Record->getIdentifier()) {
     // C++ [class.mem]p13:
     //   If T is the name of a class, then each of the following shall have a 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Feb 27 19:01:56 2015
@@ -3099,11 +3099,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, u
       }
       break;
 
-    case DYNAMIC_CLASSES:
-      for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        DynamicClasses.push_back(getGlobalDeclID(F, Record[I]));
-      break;
-
     case PENDING_IMPLICIT_INSTANTIATIONS:
       if (PendingInstantiations.size() % 2 != 0) {
         Error("Invalid existing PendingInstantiations");
@@ -7312,16 +7307,6 @@ void ASTReader::ReadExtVectorDecls(Small
   ExtVectorDecls.clear();
 }
 
-void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {
-  for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {
-    CXXRecordDecl *D
-      = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I]));
-    if (D)
-      Decls.push_back(D);
-  }
-  DynamicClasses.clear();
-}
-
 void ASTReader::ReadUnusedLocalTypedefNameCandidates(
     llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
   for (unsigned I = 0, N = UnusedLocalTypedefNameCandidates.size(); I != N;

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Feb 27 19:01:56 2015
@@ -4344,10 +4344,6 @@ void ASTWriter::WriteASTCore(Sema &SemaR
   for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
     AddDeclRef(TD, UnusedLocalTypedefNameCandidates);
 
-  // Build a record containing all of dynamic classes declarations.
-  RecordData DynamicClasses;
-  AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses);
-
   // Build a record containing all of pending implicit instantiations.
   RecordData PendingInstantiations;
   for (std::deque<Sema::PendingImplicitInstantiation>::iterator
@@ -4628,10 +4624,6 @@ void ASTWriter::WriteASTCore(Sema &SemaR
   if (!VTableUses.empty())
     Stream.EmitRecord(VTABLE_USES, VTableUses);
 
-  // Write the record containing dynamic classes declarations.
-  if (!DynamicClasses.empty())
-    Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
-
   // Write the record containing potentially unused local typedefs.
   if (!UnusedLocalTypedefNameCandidates.empty())
     Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,

Modified: cfe/trunk/test/CodeGenCXX/arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/arm64.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/arm64.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/arm64.cpp Fri Feb 27 19:01:56 2015
@@ -45,33 +45,34 @@ namespace test2 {
     virtual void foo();
   };
   void A::foo() {}
-  // Tested below because these globals get kindof oddly rearranged.
+  // CHECK-GLOBALS-DAG: @_ZTSN5test21AE = constant [11 x i8]
+  // CHECK-GLOBALS-DAG: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) }
 
   struct __attribute__((visibility("hidden"))) B {};
   const std::type_info &b0 = typeid(B);
-  // CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant
-  // CHECK-GLOBALS: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) }
+  // CHECK-GLOBALS-DAG: @_ZTSN5test21BE = linkonce_odr hidden constant
+  // CHECK-GLOBALS-DAG: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) }
 
   const std::type_info &b1 = typeid(B*);
-  // CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant
-  // CHECK-GLOBALS: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast
+  // CHECK-GLOBALS-DAG: @_ZTSPN5test21BE = linkonce_odr hidden constant
+  // CHECK-GLOBALS-DAG: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast
 
   struct C {};
   const std::type_info &c0 = typeid(C);
-  // CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr hidden constant
-  // CHECK-GLOBALS: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) }
+  // CHECK-GLOBALS-DAG: @_ZTSN5test21CE = linkonce_odr hidden constant
+  // CHECK-GLOBALS-DAG: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) }
 
   const std::type_info &c1 = typeid(C*);
-  // CHECK-GLOBALS: @_ZTSPN5test21CE = linkonce_odr hidden constant
-  // CHECK-GLOBALS: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast
+  // CHECK-GLOBALS-DAG: @_ZTSPN5test21CE = linkonce_odr hidden constant
+  // CHECK-GLOBALS-DAG: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast
 
   // This class is explicitly-instantiated, but that instantiation
   // doesn't guarantee to emit RTTI, so we can still demote the visibility.
   template <class T> class D {};
   template class D<int>;
   const std::type_info &d0 = typeid(D<int>);
-  // CHECK-GLOBALS: @_ZTSN5test21DIiEE = linkonce_odr hidden constant
-  // CHECK-GLOBALS: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) }
+  // CHECK-GLOBALS-DAG: @_ZTSN5test21DIiEE = linkonce_odr hidden constant
+  // CHECK-GLOBALS-DAG: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) }
 
   // This class is explicitly-instantiated and *does* guarantee to
   // emit RTTI, so we're stuck with having to use default visibility.
@@ -79,10 +80,7 @@ namespace test2 {
     virtual void foo() {}
   };
   template class E<int>;
-  // CHECK-GLOBALS: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8]
-  // CHECK-GLOBALS: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
-
-  // CHECK-GLOBALS: @_ZTSN5test21AE = constant [11 x i8]
-  // CHECK-GLOBALS: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) }
+  // CHECK-GLOBALS-DAG: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8]
+  // CHECK-GLOBALS-DAG: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
 
 }

Modified: cfe/trunk/test/CodeGenCXX/cxx11-vtable-key-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-vtable-key-function.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx11-vtable-key-function.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx11-vtable-key-function.cpp Fri Feb 27 19:01:56 2015
@@ -10,7 +10,7 @@ struct X {
 X::~X() = default;
 
 // Verify that the vtable is emitted.
-// CHECK: @_ZTVN5Test11XE = unnamed_addr constant
+// CHECK-DAG: @_ZTVN5Test11XE = unnamed_addr constant
 }
 
 namespace Test2 {
@@ -22,7 +22,7 @@ struct X {
 void X::f() {}
 
 // Verify that the vtable is emitted.
-// CHECK: @_ZTVN5Test21XE = unnamed_addr constant
+// CHECK-DAG: @_ZTVN5Test21XE = unnamed_addr constant
 }
 
 namespace Test3 {
@@ -34,5 +34,5 @@ struct X {
 void X::f() {}
 
 // Verify that the vtable is emitted.
-// CHECK: @_ZTVN5Test31XE = unnamed_addr constant
+// CHECK-DAG: @_ZTVN5Test31XE = unnamed_addr constant
 }

Modified: cfe/trunk/test/CodeGenCXX/key-function-vtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/key-function-vtable.cpp?rev=230830&r1=230829&r2=230830&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/key-function-vtable.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/key-function-vtable.cpp Fri Feb 27 19:01:56 2015
@@ -43,11 +43,9 @@ inline void X1::f() { }
 
 void use_X1() { X1 x1; }
 
-// FIXME: The checks are extremely difficult to get right when the globals
-// aren't alphabetized
-// CHECK: @_ZTV2X1 = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
-// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV2X1 = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null
+// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null





More information about the cfe-commits mailing list