diff --git a/clang/lib/AST/ExprConstantMeta.cpp b/clang/lib/AST/ExprConstantMeta.cpp index e5f605fc8ce2..e8329ff06da6 100644 --- a/clang/lib/AST/ExprConstantMeta.cpp +++ b/clang/lib/AST/ExprConstantMeta.cpp @@ -989,6 +989,9 @@ static bool getParameterName(ParmVarDecl *PVD, std::string &Out) { StringRef FirstNameSeen = PVD->getName(); unsigned ParamIdx = PVD->getFunctionScopeIndex(); + // TODO(P2996): This will crash if we're in the trailing requires-clause of + // a function declaration, since the DeclContext is not the function but the + // TranslationUnitDecl. FunctionDecl *FD = cast(PVD->getDeclContext()); FD = FD->getMostRecentDecl(); @@ -1019,6 +1022,9 @@ static bool getParameterName(ParmVarDecl *PVD, std::string &Out) { } static ParmVarDecl *getMostRecentParmVarDecl(ParmVarDecl *PVD) { + // TODO(P2996): This will crash if we're in the trailing requires-clause of + // a function declaration, since the DeclContext is not the function but the + // TranslationUnitDecl. FunctionDecl *FD = cast(PVD->getDeclContext()); FD = FD->getMostRecentDecl(); return FD->getParamDecl(PVD->getFunctionScopeIndex()); @@ -5570,14 +5576,22 @@ bool current_access_context(APValue &Result, ASTContext &C, MetaActions &Meta, SourceRange Range, ArrayRef Args, Decl *ContainingDecl) { assert(ResultTy == C.MetaInfoTy); + Decl *Ctx = nullptr; StackLocationExpr *SLE = StackLocationExpr::Create(C, SourceRange(), 1); - if (!Evaluator(Result, SLE, true) || !Result.isReflection()) + if (!Evaluator(Result, SLE, true) || !Result.isReflectedDecl()) return true; - else if (Result.getReflectedDecl() != nullptr) - return false; + else if (Ctx = Result.getReflectedDecl(); !Ctx) + Ctx = Meta.CurrentCtx(); - return SetAndSucceed(Result, makeReflection(Meta.CurrentCtx())); + if (auto *Ctor = dyn_cast(Ctx); + Ctor && Ctor->isInheritingConstructor()) + Ctx = cast(Ctor->getDeclContext()); + + if (auto *RD = dyn_cast(Ctx)) + return SetAndSucceed(Result, + makeReflection(QualType(RD->getTypeForDecl(), 0))); + return SetAndSucceed(Result, makeReflection(Ctx)); } bool is_accessible(APValue &Result, ASTContext &C, MetaActions &Meta, diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index f0f42322ab34..29102665aa2d 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/Support/raw_ostream.h" +#include using namespace clang; using namespace sema; diff --git a/libcxx/test/std/experimental/reflection/member-visibility.pass.cpp b/libcxx/test/std/experimental/reflection/member-visibility.pass.cpp index ee00325ac62d..ac9d6ec42f7a 100644 --- a/libcxx/test/std/experimental/reflection/member-visibility.pass.cpp +++ b/libcxx/test/std/experimental/reflection/member-visibility.pass.cpp @@ -339,4 +339,22 @@ static_assert(is_accessible(^^a, std::meta::access_context::unprivileged())); } // namespace anonymous_structs_unions + // ======================== + // default_mem_initializers + // ======================== + +namespace default_mem_initializers { +struct A { + int a; + consteval A(int p) : a(p) {} +}; +struct B : A { + using A::A; + consteval B(int p, int q) : A(p * q) {} + std::meta::info s = std::meta::access_context::current().scope(); +}; +static_assert(B(1).s == ^^B); +static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); +} // namespace default_mem_initializers + int main() { }