forked from OSchip/llvm-project
Modules: Search for a visible definition of the decl context when computing visibility of a default template parameter
The code is/was already correct for the case where a parameter is a parameter of its enclosing lexical DeclContext (functions and classes). But for other templates (alias and variable templates) they don't create their own scope to be members of - in those cases, they parameter should be considered visible if any definition of the lexical decl context is visible. [this should cleanup the failure on the libstdc++ modules buildbot] [this doesn't actually fix the variable template case for a secondary/compounding reason (its lexical decl context is incorrectly considered to be the translation unit)] Test covers all 4 kinds of templates with default args, including a regression test for the still broken variable template case. Reviewers: rsmith Differential Revision: https://reviews.llvm.org/D60892 llvm-svn: 358795
This commit is contained in:
parent
a30920c31f
commit
aa3bf6ce72
|
@ -1543,8 +1543,21 @@ bool LookupResult::isVisibleSlow(Sema &SemaRef, NamedDecl *D) {
|
|||
// and in C we must not because each declaration of a function gets its own
|
||||
// set of declarations for tags in prototype scope.
|
||||
bool VisibleWithinParent;
|
||||
if (D->isTemplateParameter() || isa<ParmVarDecl>(D) ||
|
||||
(isa<FunctionDecl>(DC) && !SemaRef.getLangOpts().CPlusPlus))
|
||||
if (D->isTemplateParameter()) {
|
||||
bool SearchDefinitions = true;
|
||||
if (const auto *DCD = dyn_cast<Decl>(DC)) {
|
||||
if (const auto *TD = DCD->getDescribedTemplate()) {
|
||||
TemplateParameterList *TPL = TD->getTemplateParameters();
|
||||
auto Index = getDepthAndIndex(D).second;
|
||||
SearchDefinitions = Index >= TPL->size() || TPL->getParam(Index) != D;
|
||||
}
|
||||
}
|
||||
if (SearchDefinitions)
|
||||
VisibleWithinParent = SemaRef.hasVisibleDefinition(cast<NamedDecl>(DC));
|
||||
else
|
||||
VisibleWithinParent = isVisible(SemaRef, cast<NamedDecl>(DC));
|
||||
} else if (isa<ParmVarDecl>(D) ||
|
||||
(isa<FunctionDecl>(DC) && !SemaRef.getLangOpts().CPlusPlus))
|
||||
VisibleWithinParent = isVisible(SemaRef, cast<NamedDecl>(DC));
|
||||
else if (D->isModulePrivate()) {
|
||||
// A module-private declaration is only visible if an enclosing lexical
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef ALIAS_H
|
||||
#define ALIAS_H
|
||||
struct alias_outer {
|
||||
template <typename = int>
|
||||
using alias = int;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#include "alias.h"
|
|
@ -0,0 +1 @@
|
|||
#include "alias.h"
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef FUNC_H
|
||||
#define FUNC_H
|
||||
struct func_outer {
|
||||
template <typename = int>
|
||||
void func();
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#include "func.h"
|
|
@ -0,0 +1 @@
|
|||
#include "func.h"
|
|
@ -0,0 +1,24 @@
|
|||
module ALIAS1 {
|
||||
header "alias1.h"
|
||||
module ALIAS2 {
|
||||
header "alias2.h"
|
||||
}
|
||||
}
|
||||
module VAR1 {
|
||||
header "var1.h"
|
||||
module VAR2 {
|
||||
header "var2.h"
|
||||
}
|
||||
}
|
||||
module FUNC1 {
|
||||
header "func1.h"
|
||||
module FUNC2 {
|
||||
header "func2.h"
|
||||
}
|
||||
}
|
||||
module STRCT1 {
|
||||
header "strct1.h"
|
||||
module STRCT2 {
|
||||
header "strct2.h"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef STRCT_H
|
||||
#define STRCT_H
|
||||
struct strct_outer {
|
||||
template <typename = int>
|
||||
struct strct;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
#include "strct.h"
|
|
@ -0,0 +1 @@
|
|||
#include "strct.h"
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef VAR_H
|
||||
#define VAR_H
|
||||
struct var_outer {
|
||||
template <typename = int>
|
||||
static int var;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include "var.h"
|
|
@ -0,0 +1 @@
|
|||
#include "var.h"
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
|
||||
// RUN: -I %S/Inputs/nested-template-default-arg-redecl -std=c++14 \
|
||||
// RUN: -fmodules-local-submodule-visibility -verify %s
|
||||
#include "alias2.h"
|
||||
#include "var2.h"
|
||||
#include "strct2.h"
|
||||
#include "func2.h"
|
||||
|
||||
// FIXME: Variable templates lexical decl context appears to be the translation
|
||||
// unit, which is incorrect. Fixing this will hopefully address the following
|
||||
// error/bug:
|
||||
|
||||
// expected-note@Inputs/nested-template-default-arg-redecl/var.h:4 {{default argument declared here}}
|
||||
auto var = &var_outer::var<>; // expected-error {{default argument of 'var' must be imported from module 'VAR1' before it is required}}
|
||||
auto func = &func_outer::func<>;
|
||||
strct_outer::strct<> *strct;
|
||||
alias_outer::alias<> *alias;
|
Loading…
Reference in New Issue