vsapsai updated this revision to Diff 137801.
vsapsai added a comment.

- Claim the definition data more eagerly.

Not sure that added "different" in the existing comment is actually useful.
It makes sense to me but don't know about others.


https://reviews.llvm.org/D43494

Files:
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/test/Modules/Inputs/self-referencing-lambda/a.h
  clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
  clang/test/Modules/self-referencing-lambda.cpp


Index: clang/test/Modules/self-referencing-lambda.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/self-referencing-lambda.cpp
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I 
%S/Inputs/self-referencing-lambda %s -verify -emit-obj -o %t2.o
+// expected-no-diagnostics
+
+#include "a.h"
Index: clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
@@ -0,0 +1,4 @@
+module "a.h" {
+  header "a.h"
+  export *
+}
Index: clang/test/Modules/Inputs/self-referencing-lambda/a.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/self-referencing-lambda/a.h
@@ -0,0 +1,4 @@
+void f() {
+  int x = 0;
+  auto q = [xm = x]{};
+}
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1782,21 +1782,27 @@
   else
     DD = new (C) struct CXXRecordDecl::DefinitionData(D);
 
+  CXXRecordDecl *Canon = D->getCanonicalDecl();
+  // Set decl definition data before reading it, so that during deserialization
+  // when we read CXXRecordDecl, it already has definition data and we don't
+  // set fake one.
+  if (!Canon->DefinitionData) {
+    Canon->DefinitionData = DD;
+  }
+  D->DefinitionData = Canon->DefinitionData;
   ReadCXXDefinitionData(*DD, D);
 
-  // We might already have a definition for this record. This can happen either
-  // because we're reading an update record, or because we've already done some
-  // merging. Either way, just merge into it.
-  CXXRecordDecl *Canon = D->getCanonicalDecl();
-  if (Canon->DefinitionData) {
+  // We might already have a different definition for this record. This can
+  // happen either because we're reading an update record, or because we've
+  // already done some merging. Either way, just merge into it.
+  if (Canon->DefinitionData && Canon->DefinitionData != DD) {
     MergeDefinitionData(Canon, std::move(*DD));
     D->DefinitionData = Canon->DefinitionData;
     return;
   }
 
   // Mark this declaration as being a definition.
   D->IsCompleteDefinition = true;
-  D->DefinitionData = DD;
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the


Index: clang/test/Modules/self-referencing-lambda.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/self-referencing-lambda.cpp
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/self-referencing-lambda %s -verify -emit-obj -o %t2.o
+// expected-no-diagnostics
+
+#include "a.h"
Index: clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/self-referencing-lambda/module.modulemap
@@ -0,0 +1,4 @@
+module "a.h" {
+  header "a.h"
+  export *
+}
Index: clang/test/Modules/Inputs/self-referencing-lambda/a.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/self-referencing-lambda/a.h
@@ -0,0 +1,4 @@
+void f() {
+  int x = 0;
+  auto q = [xm = x]{};
+}
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1782,21 +1782,27 @@
   else
     DD = new (C) struct CXXRecordDecl::DefinitionData(D);
 
+  CXXRecordDecl *Canon = D->getCanonicalDecl();
+  // Set decl definition data before reading it, so that during deserialization
+  // when we read CXXRecordDecl, it already has definition data and we don't
+  // set fake one.
+  if (!Canon->DefinitionData) {
+    Canon->DefinitionData = DD;
+  }
+  D->DefinitionData = Canon->DefinitionData;
   ReadCXXDefinitionData(*DD, D);
 
-  // We might already have a definition for this record. This can happen either
-  // because we're reading an update record, or because we've already done some
-  // merging. Either way, just merge into it.
-  CXXRecordDecl *Canon = D->getCanonicalDecl();
-  if (Canon->DefinitionData) {
+  // We might already have a different definition for this record. This can
+  // happen either because we're reading an update record, or because we've
+  // already done some merging. Either way, just merge into it.
+  if (Canon->DefinitionData && Canon->DefinitionData != DD) {
     MergeDefinitionData(Canon, std::move(*DD));
     D->DefinitionData = Canon->DefinitionData;
     return;
   }
 
   // Mark this declaration as being a definition.
   D->IsCompleteDefinition = true;
-  D->DefinitionData = DD;
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to