forked from OSchip/llvm-project
Support for merging UsingPackDecls across modules.
Fixes a false-positive error if the same std::variant<...> type is instantiated across multiple modules.
This commit is contained in:
parent
f6b6e72143
commit
9ab5f76117
|
@ -3067,7 +3067,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Determine whether the two declarations refer to the same entity.pr
|
||||
/// Determine whether the two declarations refer to the same entity.
|
||||
static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
|
||||
assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
|
||||
|
||||
|
@ -3261,10 +3261,19 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
|
|||
return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
|
||||
UX->isAccessDeclaration() == UY->isAccessDeclaration();
|
||||
}
|
||||
if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X))
|
||||
if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) {
|
||||
return isSameQualifier(
|
||||
UX->getQualifier(),
|
||||
cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier());
|
||||
}
|
||||
|
||||
// Using-pack declarations are only created by instantiation, and match if
|
||||
// they're instantiated from matching UnresolvedUsing...Decls.
|
||||
if (const auto *UX = dyn_cast<UsingPackDecl>(X)) {
|
||||
return declaresSameEntity(
|
||||
UX->getInstantiatedFromUsingDecl(),
|
||||
cast<UsingPackDecl>(Y)->getInstantiatedFromUsingDecl());
|
||||
}
|
||||
|
||||
// Namespace alias definitions with the same target match.
|
||||
if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
struct X {
|
||||
int v;
|
||||
typedef int t;
|
||||
void f(X);
|
||||
};
|
||||
|
||||
struct YA {
|
||||
|
@ -8,6 +9,10 @@ struct YA {
|
|||
typedef int type;
|
||||
};
|
||||
|
||||
struct Z {
|
||||
void f(Z);
|
||||
};
|
||||
|
||||
template<typename T> struct C : X, T {
|
||||
using T::value;
|
||||
using typename T::type;
|
||||
|
@ -41,3 +46,10 @@ typedef C<YA>::type I;
|
|||
typedef D<YA>::type I;
|
||||
typedef E<YA>::type I;
|
||||
typedef F<YA>::type I;
|
||||
|
||||
#if __cplusplus >= 201702L
|
||||
template<typename ...T> struct G : T... {
|
||||
using T::f...;
|
||||
};
|
||||
using Q = decltype(G<X, Z>());
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
struct X {
|
||||
int v;
|
||||
typedef int t;
|
||||
void f(X);
|
||||
};
|
||||
|
||||
struct YB {
|
||||
|
@ -14,6 +15,10 @@ struct YBRev {
|
|||
int type;
|
||||
};
|
||||
|
||||
struct Z {
|
||||
void f(Z);
|
||||
};
|
||||
|
||||
template<typename T> struct C : X, T {
|
||||
using T::value;
|
||||
using typename T::type;
|
||||
|
@ -54,3 +59,10 @@ typedef E<YB>::type I;
|
|||
#endif
|
||||
|
||||
typedef F<YB>::type I;
|
||||
|
||||
#if __cplusplus >= 201702L
|
||||
template<typename ...T> struct G : T... {
|
||||
using T::f...;
|
||||
};
|
||||
using Q = decltype(G<X, Z>());
|
||||
#endif
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=1
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=1
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=1
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++17 %s -DORDER=1
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=2
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=2
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=2
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++17 %s -DORDER=2
|
||||
|
||||
#if ORDER == 1
|
||||
#include "a.h"
|
||||
|
@ -39,6 +41,19 @@ template int UseAll<YA>();
|
|||
template int UseAll<YB>();
|
||||
template int UseAll<Y>();
|
||||
|
||||
#if __cplusplus >= 201702L
|
||||
void use_g(Q q) {
|
||||
q.f(q); // expected-error {{ambiguous}}
|
||||
#if ORDER == 1
|
||||
// expected-note@a.h:* {{candidate function}}
|
||||
// expected-note@a.h:* {{candidate function}}
|
||||
#else
|
||||
// expected-note@b.h:* {{candidate function}}
|
||||
// expected-note@b.h:* {{candidate function}}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Which of these two sets of diagnostics is chosen is not important. It's OK
|
||||
// if this varies with ORDER, but it must be consistent across runs.
|
||||
#if ORDER == 1
|
||||
|
|
Loading…
Reference in New Issue