summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-06-16 20:26:19 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-06-16 20:26:19 +0000
commite4d7f02c0699f734a9ea83e2dc4b5512f4700ec0 (patch)
tree872b6f4bb3e184c270f6cccedf3b1f60dfa34887
parent7fe5bef6d6863f247222706806b80782ded8abb9 (diff)
downloadclang-e4d7f02c0699f734a9ea83e2dc4b5512f4700ec0.tar.gz
clang-e4d7f02c0699f734a9ea83e2dc4b5512f4700ec0.tar.bz2
clang-e4d7f02c0699f734a9ea83e2dc4b5512f4700ec0.tar.xz
[modules] When we merge redecl chains or mark a decl used with an update
record, mark all subsequent decls as 'used' too, to maintain the AST invariant that getPreviousDecl()->Used implies this->Used. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211050 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Serialization/ASTReader.cpp5
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp14
-rw-r--r--test/Modules/Inputs/cxx-decls-imported.h3
-rw-r--r--test/Modules/Inputs/cxx-decls-merged.h1
-rw-r--r--test/Modules/Inputs/module.map4
-rw-r--r--test/Modules/cxx-decls.cpp8
6 files changed, 33 insertions, 2 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index e8db122445..0c9f263faf 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -8088,7 +8088,10 @@ void ASTReader::finishPendingActions() {
}
// Perform any pending declaration updates.
- while (!PendingUpdateRecords.empty()) {
+ //
+ // Don't do this if we have known-incomplete redecl chains: it relies on
+ // being able to walk redeclaration chains.
+ while (PendingDeclChains.empty() && !PendingUpdateRecords.empty()) {
auto Update = PendingUpdateRecords.pop_back_val();
ReadingKindTracker ReadingKind(Read_Decl, *this);
loadDeclUpdateRecords(Update.first, Update.second);
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 7e652c4718..47748a33f7 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -2492,6 +2492,11 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *Previous) {
Previous->IdentifierNamespace &
(Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
+ // If the previous declaration is marked as used, then this declaration should
+ // be too.
+ if (Previous->Used)
+ D->Used = true;
+
// If the previous declaration is an inline function declaration, then this
// declaration is too.
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
@@ -3280,7 +3285,14 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
case UPD_DECL_MARKED_USED: {
// FIXME: This doesn't send the right notifications if there are
// ASTMutationListeners other than an ASTWriter.
- D->Used = true;
+
+ // Maintain AST consistency: any later redeclarations are used too.
+ for (auto *Redecl = D->getMostRecentDecl(); /**/;
+ Redecl = Redecl->getPreviousDecl()) {
+ Redecl->Used = true;
+ if (Redecl == D)
+ break;
+ }
break;
}
diff --git a/test/Modules/Inputs/cxx-decls-imported.h b/test/Modules/Inputs/cxx-decls-imported.h
index 5c7f6fc344..38cc00d863 100644
--- a/test/Modules/Inputs/cxx-decls-imported.h
+++ b/test/Modules/Inputs/cxx-decls-imported.h
@@ -20,3 +20,6 @@ static_assert(!__is_trivial(HasNontrivialDefaultConstructor), "");
static_assert(!__has_trivial_constructor(HasNontrivialDefaultConstructor), "");
void *operator new[](__SIZE_TYPE__);
+
+extern int mergeUsedFlag;
+inline int getMergeUsedFlag() { return mergeUsedFlag; }
diff --git a/test/Modules/Inputs/cxx-decls-merged.h b/test/Modules/Inputs/cxx-decls-merged.h
new file mode 100644
index 0000000000..ccc3b01548
--- /dev/null
+++ b/test/Modules/Inputs/cxx-decls-merged.h
@@ -0,0 +1 @@
+extern int mergeUsedFlag;
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index a85145f871..fea1201523 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -238,6 +238,10 @@ module cxx_decls {
}
}
+module cxx_decls_merged {
+ header "cxx-decls-merged.h"
+}
+
module config {
header "config.h"
config_macros [exhaustive] WANT_FOO, WANT_BAR
diff --git a/test/Modules/cxx-decls.cpp b/test/Modules/cxx-decls.cpp
index 49ba8340d3..5498b47fc9 100644
--- a/test/Modules/cxx-decls.cpp
+++ b/test/Modules/cxx-decls.cpp
@@ -1,5 +1,6 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -ast-dump -ast-dump-filter merge -std=c++11 | FileCheck %s
// expected-no-diagnostics
@@ -26,3 +27,10 @@ static_assert(!__is_trivial(HasNontrivialDefaultConstructor), "");
static_assert(!__has_trivial_constructor(HasNontrivialDefaultConstructor), "");
void use_implicit_new_again() { operator new[](3); }
+
+int importMergeUsedFlag = getMergeUsedFlag();
+
+@import cxx_decls_merged;
+
+// CHECK: VarDecl [[mergeUsedFlag:0x[0-9a-f]*]] {{.*}} in cxx_decls.imported used mergeUsedFlag
+// CHECK: VarDecl {{0x[0-9a-f]*}} prev [[mergeUsedFlag]] {{.*}} in cxx_decls_merged used mergeUsedFlag