diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 316a7ed5fa1bb..dd8868d0b1ec2 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -83,63 +83,47 @@ void Pointer::operator=(Pointer &&P) { } APValue Pointer::toAPValue() const { - APValue::LValueBase Base; llvm::SmallVector Path; - CharUnits Offset; - bool IsNullPtr; - bool IsOnePastEnd; - - if (isZero()) { - Base = static_cast(nullptr); - IsNullPtr = true; - IsOnePastEnd = false; - Offset = CharUnits::Zero(); - } else { - // Build the lvalue base from the block. - const Descriptor *Desc = getDeclDesc(); - if (auto *VD = Desc->asValueDecl()) - Base = VD; - else if (auto *E = Desc->asExpr()) - Base = E; - else - llvm_unreachable("Invalid allocation type"); - - // Not a null pointer. - IsNullPtr = false; - - if (isUnknownSizeArray()) { - IsOnePastEnd = false; - Offset = CharUnits::Zero(); - } else if (Desc->asExpr()) { - // Pointer pointing to a an expression. - IsOnePastEnd = false; - Offset = CharUnits::Zero(); + + if (isZero()) + return APValue(static_cast(nullptr), CharUnits::Zero(), Path, + false, /*IsNullPtr=*/false); + + // Build the lvalue base from the block. + const Descriptor *Desc = getDeclDesc(); + APValue::LValueBase Base; + if (auto *VD = Desc->asValueDecl()) + Base = VD; + else if (auto *E = Desc->asExpr()) + Base = E; + else + llvm_unreachable("Invalid allocation type"); + + if (isUnknownSizeArray() || Desc->asExpr()) + return APValue(Base, CharUnits::Zero(), Path, false, false); + + // TODO: compute the offset into the object. + CharUnits Offset = CharUnits::Zero(); + bool IsOnePastEnd = isOnePastEnd(); + + // Build the path into the object. + Pointer Ptr = *this; + while (Ptr.isField() || Ptr.isArrayElement()) { + if (Ptr.isArrayElement()) { + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getIndex())); + Ptr = Ptr.getArray(); } else { - // TODO: compute the offset into the object. - Offset = CharUnits::Zero(); - - // Build the path into the object. - Pointer Ptr = *this; - while (Ptr.isField() || Ptr.isArrayElement()) { - if (Ptr.isArrayElement()) { - Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getIndex())); - Ptr = Ptr.getArray(); - } else { - // TODO: figure out if base is virtual - bool IsVirtual = false; - - // Create a path entry for the field. - const Descriptor *Desc = Ptr.getFieldDesc(); - if (const auto *BaseOrMember = Desc->asDecl()) { - Path.push_back(APValue::LValuePathEntry({BaseOrMember, IsVirtual})); - Ptr = Ptr.getBase(); - continue; - } - llvm_unreachable("Invalid field type"); - } + // TODO: figure out if base is virtual + bool IsVirtual = false; + + // Create a path entry for the field. + const Descriptor *Desc = Ptr.getFieldDesc(); + if (const auto *BaseOrMember = Desc->asDecl()) { + Path.push_back(APValue::LValuePathEntry({BaseOrMember, IsVirtual})); + Ptr = Ptr.getBase(); + continue; } - - IsOnePastEnd = isOnePastEnd(); + llvm_unreachable("Invalid field type"); } } @@ -149,7 +133,7 @@ APValue Pointer::toAPValue() const { // Just invert the order of the elements. std::reverse(Path.begin(), Path.end()); - return APValue(Base, Offset, Path, IsOnePastEnd, IsNullPtr); + return APValue(Base, Offset, Path, IsOnePastEnd, /*IsNullPtr=*/false); } std::string Pointer::toDiagnosticString(const ASTContext &Ctx) const {