diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-16 20:26:19 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-16 20:26:19 +0000 |
commit | e4d7f02c0699f734a9ea83e2dc4b5512f4700ec0 (patch) | |
tree | 872b6f4bb3e184c270f6cccedf3b1f60dfa34887 | |
parent | 7fe5bef6d6863f247222706806b80782ded8abb9 (diff) | |
download | clang-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.cpp | 5 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 14 | ||||
-rw-r--r-- | test/Modules/Inputs/cxx-decls-imported.h | 3 | ||||
-rw-r--r-- | test/Modules/Inputs/cxx-decls-merged.h | 1 | ||||
-rw-r--r-- | test/Modules/Inputs/module.map | 4 | ||||
-rw-r--r-- | test/Modules/cxx-decls.cpp | 8 |
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 |