Extraction of arrays as pointers.

This commit is contained in:
Dan Katz
2025-05-16 12:00:24 -04:00
parent d62cc2e0ce
commit 5383f737ca
2 changed files with 32 additions and 3 deletions

View File

@@ -3081,10 +3081,29 @@ bool extract(APValue &Result, ASTContext &C, MetaActions &Meta,
}
Synthesized = DeclRefExpr::Create(C, NNSLocBuilder.getTemporary(),
SourceLocation(), Decl, false,
Range.getBegin(), ResultTy,
ReturnsLValue ? VK_LValue :
VK_PRValue,
Range.getBegin(), ResultTy, VK_LValue,
Decl, nullptr);
} else if (auto *ArrTy = dyn_cast<ArrayType>(Decl->getType())) {
QualType PtrTy = C.getPointerType(ArrTy->getElementType());
ReturnsLValue = true;
if (RawResultTy.getCanonicalType().getTypePtr() !=
PtrTy.getCanonicalType().getTypePtr())
return Diagnoser(Range.getBegin(), diag::metafn_extract_type_mismatch)
<< 1 << PtrTy << 1 << ResultTy << Range;
NestedNameSpecifierLocBuilder NNSLocBuilder;
if (auto *ParentClsDecl = dyn_cast_or_null<CXXRecordDecl>(
Decl->getDeclContext())) {
TypeSourceInfo *TSI = C.CreateTypeSourceInfo(
QualType(ParentClsDecl->getTypeForDecl(), 0), 0);
NNSLocBuilder.Extend(C, Range.getBegin(), TSI->getTypeLoc(),
Range.getBegin());
}
APValue::LValuePathEntry Path[1] = {APValue::LValuePathEntry::ArrayIndex(0)};
return SetAndSucceed(Result,
APValue(Decl, CharUnits::Zero(), Path, false));
} else {
// We have a reflection of a (possibly local) non-reference variable.
// Synthesize an lvalue by reaching up the call stack.

View File

@@ -205,6 +205,16 @@ namespace extract_ref_semantics {
}
} // namespace extract_ref_semantics
// ====================
// extract_array_as_ptr
// ====================
namespace extract_array_as_ptr {
constexpr int arr[] = {1, 2, 3};
static_assert(extract<const int *>(^^arr)[2] == 3);
} // namespace extract_array_as_ptr
// ==============
// value_of_types
// ==============