From: Richard Smith Date: Sat, 20 Jun 2015 01:05:19 +0000 (+0000) Subject: [modules] When determining whether a definition of a class is visible, check all... X-Git-Tag: llvmorg-3.7.0-rc1~1935 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=beb44788b36a3ab7db82d5ae4dd52d571d159bd6;p=platform%2Fupstream%2Fllvm.git [modules] When determining whether a definition of a class is visible, check all modules even if we've already found a definition that's not visible. llvm-svn: 240204 --- diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index ff0e26c..d72f259 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5973,10 +5973,18 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested) { } assert(D && "missing definition for pattern of instantiated definition"); - // FIXME: If we merged any other decl into D, and that declaration is visible, - // then we should consider a definition to be visible. *Suggested = D; - return LookupResult::isVisible(*this, D); + if (LookupResult::isVisible(*this, D)) + return true; + + // The external source may have additional definitions of this type that are + // visible, so complete the redeclaration chain now and ask again. + if (auto *Source = Context.getExternalSource()) { + Source->CompleteRedeclChain(D); + return LookupResult::isVisible(*this, D); + } + + return false; } /// Locks in the inheritance model for the given class and all of its bases. diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 2e13a9b..00ebd3e 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3890,6 +3890,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, case UPD_DECL_EXPORTED: unsigned SubmoduleID = readSubmoduleID(Record, Idx); + auto *Exported = cast(D); + if (auto *TD = dyn_cast(Exported)) + Exported = TD->getDefinition(); Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr; if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { // FIXME: This doesn't send the right notifications if there are diff --git a/clang/test/Modules/Inputs/merge-class-definition-visibility/a.h b/clang/test/Modules/Inputs/merge-class-definition-visibility/a.h new file mode 100644 index 0000000..4c5cd94 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-class-definition-visibility/a.h @@ -0,0 +1 @@ +struct A {}; diff --git a/clang/test/Modules/Inputs/merge-class-definition-visibility/b.h b/clang/test/Modules/Inputs/merge-class-definition-visibility/b.h new file mode 100644 index 0000000..2b8f5f8 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-class-definition-visibility/b.h @@ -0,0 +1,2 @@ +// Include definition of A into the same module as c.h +#include "a.h" diff --git a/clang/test/Modules/Inputs/merge-class-definition-visibility/c.h b/clang/test/Modules/Inputs/merge-class-definition-visibility/c.h new file mode 100644 index 0000000..27f503c --- /dev/null +++ b/clang/test/Modules/Inputs/merge-class-definition-visibility/c.h @@ -0,0 +1 @@ +struct A; diff --git a/clang/test/Modules/Inputs/merge-class-definition-visibility/d.h b/clang/test/Modules/Inputs/merge-class-definition-visibility/d.h new file mode 100644 index 0000000..2243de1 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-class-definition-visibility/d.h @@ -0,0 +1 @@ +#include "a.h" diff --git a/clang/test/Modules/Inputs/merge-class-definition-visibility/modmap b/clang/test/Modules/Inputs/merge-class-definition-visibility/modmap new file mode 100644 index 0000000..7d988fb --- /dev/null +++ b/clang/test/Modules/Inputs/merge-class-definition-visibility/modmap @@ -0,0 +1,7 @@ +module Def1 { + module B { header "b.h" } + module C { header "c.h" } +} +module Def2 { + header "d.h" +} diff --git a/clang/test/Modules/merge-class-definition-visibility.cpp b/clang/test/Modules/merge-class-definition-visibility.cpp new file mode 100644 index 0000000..e8602c0 --- /dev/null +++ b/clang/test/Modules/merge-class-definition-visibility.cpp @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/merge-class-definition-visibility/modmap \ +// RUN: -I%S/Inputs/merge-class-definition-visibility \ +// RUN: -fmodules-cache-path=%t %s -verify +// expected-no-diagnostics + +#include "c.h" +template struct X { T t; }; +typedef X XA; + +#include "d.h" +// Ensure that this triggers the import of the second definition from d.h, +// which is necessary to make the definition of A visible in the template +// instantiation. +XA xa;