From: Douglas Gregor Date: Thu, 5 Jan 2012 01:11:47 +0000 (+0000) Subject: When we're performing name lookup for a tag, we still allow ourselves X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=447af24a003aa8d0dc7317a56f06f5b8361f8808;p=clang When we're performing name lookup for a tag, we still allow ourselves to see hidden declarations because every tag lookup is effectively a redeclaration lookup. For example, image that struct foo; is declared in a submodule that is known but hasn't been imported. If someone later writes struct foo *foo_p; then "struct foo" is either a reference or a redeclaration. To keep the redeclaration chains sound, we treat it like a redeclaration for name-lookup purposes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147588 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 1b991cb54b..6486e53bed 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -214,6 +214,12 @@ public: return Redecl; } + /// \brief Determine whether this lookup is permitted to see hidden + /// declarations, such as those in modules that have not yet been imported. + bool isHiddenDeclarationVisible() const { + return Redecl || LookupKind == Sema::LookupTagName; + } + /// Sets whether tag declarations should be hidden by non-tag /// declarations during resolution. The default is true. void setHideTags(bool Hide) { @@ -286,7 +292,7 @@ public: if (!D->isInIdentifierNamespace(IDNS)) return 0; - if (Redecl == Sema::ForRedeclaration || isVisible(D)) + if (isHiddenDeclarationVisible() || isVisible(D)) return D; return getAcceptableDeclSlow(D); diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index ae950ff27a..7ee50e3a4c 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1171,7 +1171,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) { // If this declaration is module-private and it came from an AST // file, we can't see it. - NamedDecl *D = R.isForRedeclaration()? *I : getVisibleDecl(*I); + NamedDecl *D = R.isHiddenDeclarationVisible()? *I : getVisibleDecl(*I); if (!D) continue; @@ -1194,7 +1194,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) { if (!LastDC->isFileContext() && !S->isDeclScope(*LastI)) break; - D = R.isForRedeclaration()? *LastI : getVisibleDecl(*LastI); + D = R.isHiddenDeclarationVisible()? *LastI : getVisibleDecl(*LastI); if (D) R.addDecl(D); } diff --git a/test/Modules/Inputs/redecl-merge-top-explicit.h b/test/Modules/Inputs/redecl-merge-top-explicit.h index 54aab33e6c..e06ff7aeda 100644 --- a/test/Modules/Inputs/redecl-merge-top-explicit.h +++ b/test/Modules/Inputs/redecl-merge-top-explicit.h @@ -5,3 +5,5 @@ int *explicit_func(void); struct explicit_struct { int member; }; #define ONE 1 + +typedef struct my_struct_type *my_struct_ref; diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index b41986609c..09898a5b3b 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -1,11 +1,11 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fmodule-cache-path %t -I %S/Inputs %s -verify +// RUN: %clang_cc1 -fmodules -fmodule-cache-path %t -Wno-typedef-redefinition -I %S/Inputs %s -verify // RUN: %clang_cc1 -x objective-c++ -fmodules -fmodule-cache-path %t -I %S/Inputs %s -verify @class C2; @class C3; @class C3; @import redecl_merge_left; - +typedef struct my_struct_type *my_struct_ref; @protocol P4; @class C3; @class C3;