aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/APValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/APValue.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/APValue.cpp113
1 files changed, 95 insertions, 18 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/APValue.cpp b/contrib/llvm-project/clang/lib/AST/APValue.cpp
index 9a9233bc1ea7..4eae308ef5b3 100644
--- a/contrib/llvm-project/clang/lib/AST/APValue.cpp
+++ b/contrib/llvm-project/clang/lib/AST/APValue.cpp
@@ -156,10 +156,10 @@ void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID &ID) const {
APValue::LValuePathSerializationHelper::LValuePathSerializationHelper(
ArrayRef<LValuePathEntry> Path, QualType ElemTy)
- : ElemTy((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {}
+ : Ty((const void *)ElemTy.getTypePtrOrNull()), Path(Path) {}
QualType APValue::LValuePathSerializationHelper::getType() {
- return QualType::getFromOpaquePtr(ElemTy);
+ return QualType::getFromOpaquePtr(Ty);
}
namespace {
@@ -390,11 +390,13 @@ APValue &APValue::operator=(const APValue &RHS) {
}
APValue &APValue::operator=(APValue &&RHS) {
- if (Kind != None && Kind != Indeterminate)
- DestroyDataAndMakeUninit();
- Kind = RHS.Kind;
- Data = RHS.Data;
- RHS.Kind = None;
+ if (this != &RHS) {
+ if (Kind != None && Kind != Indeterminate)
+ DestroyDataAndMakeUninit();
+ Kind = RHS.Kind;
+ Data = RHS.Data;
+ RHS.Kind = None;
+ }
return *this;
}
@@ -625,6 +627,69 @@ static double GetApproxValue(const llvm::APFloat &F) {
return V.convertToDouble();
}
+static bool TryPrintAsStringLiteral(raw_ostream &Out,
+ const PrintingPolicy &Policy,
+ const ArrayType *ATy,
+ ArrayRef<APValue> Inits) {
+ if (Inits.empty())
+ return false;
+
+ QualType Ty = ATy->getElementType();
+ if (!Ty->isAnyCharacterType())
+ return false;
+
+ // Nothing we can do about a sequence that is not null-terminated
+ if (!Inits.back().isInt() || !Inits.back().getInt().isZero())
+ return false;
+
+ Inits = Inits.drop_back();
+
+ llvm::SmallString<40> Buf;
+ Buf.push_back('"');
+
+ // Better than printing a two-digit sequence of 10 integers.
+ constexpr size_t MaxN = 36;
+ StringRef Ellipsis;
+ if (Inits.size() > MaxN && !Policy.EntireContentsOfLargeArray) {
+ Ellipsis = "[...]";
+ Inits =
+ Inits.take_front(std::min(MaxN - Ellipsis.size() / 2, Inits.size()));
+ }
+
+ for (auto &Val : Inits) {
+ if (!Val.isInt())
+ return false;
+ int64_t Char64 = Val.getInt().getExtValue();
+ if (!isASCII(Char64))
+ return false; // Bye bye, see you in integers.
+ auto Ch = static_cast<unsigned char>(Char64);
+ // The diagnostic message is 'quoted'
+ StringRef Escaped = escapeCStyle<EscapeChar::SingleAndDouble>(Ch);
+ if (Escaped.empty()) {
+ if (!isPrintable(Ch))
+ return false;
+ Buf.emplace_back(Ch);
+ } else {
+ Buf.append(Escaped);
+ }
+ }
+
+ Buf.append(Ellipsis);
+ Buf.push_back('"');
+
+ if (Ty->isWideCharType())
+ Out << 'L';
+ else if (Ty->isChar8Type())
+ Out << "u8";
+ else if (Ty->isChar16Type())
+ Out << 'u';
+ else if (Ty->isChar32Type())
+ Out << 'U';
+
+ Out << Buf;
+ return true;
+}
+
void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
QualType Ty) const {
printPretty(Out, Ctx.getPrintingPolicy(), Ty, &Ctx);
@@ -700,7 +765,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
if (!hasLValuePath()) {
// No lvalue path: just print the offset.
CharUnits O = getLValueOffset();
- CharUnits S = Ctx ? Ctx->getTypeSizeInChars(InnerTy) : CharUnits::Zero();
+ CharUnits S = Ctx ? Ctx->getTypeSizeInCharsIfKnown(InnerTy).value_or(
+ CharUnits::Zero())
+ : CharUnits::Zero();
if (!O.isZero()) {
if (IsReference)
Out << "*(";
@@ -774,6 +841,10 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
Out << *VD;
ElemTy = VD->getType();
}
+ } else if (ElemTy->isAnyComplexType()) {
+ // The lvalue refers to a complex type
+ Out << (Path[I].getAsArrayIndex() == 0 ? ".real" : ".imag");
+ ElemTy = ElemTy->castAs<ComplexType>()->getElementType();
} else {
// The lvalue must refer to an array.
Out << '[' << Path[I].getAsArrayIndex() << ']';
@@ -793,17 +864,23 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
}
case APValue::Array: {
const ArrayType *AT = Ty->castAsArrayTypeUnsafe();
+ unsigned N = getArrayInitializedElts();
+ if (N != 0 && TryPrintAsStringLiteral(Out, Policy, AT,
+ {&getArrayInitializedElt(0), N}))
+ return;
QualType ElemTy = AT->getElementType();
Out << '{';
- if (unsigned N = getArrayInitializedElts()) {
- getArrayInitializedElt(0).printPretty(Out, Policy, ElemTy, Ctx);
- for (unsigned I = 1; I != N; ++I) {
+ unsigned I = 0;
+ switch (N) {
+ case 0:
+ for (; I != N; ++I) {
Out << ", ";
- if (I == 10) {
- // Avoid printing out the entire contents of large arrays.
- Out << "...";
- break;
+ if (I == 10 && !Policy.EntireContentsOfLargeArray) {
+ Out << "...}";
+ return;
}
+ [[fallthrough]];
+ default:
getArrayInitializedElt(I).printPretty(Out, Policy, ElemTy, Ctx);
}
}
@@ -913,7 +990,7 @@ bool APValue::hasLValuePath() const {
ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
assert(isLValue() && hasLValuePath() && "Invalid accessor");
const LV &LVal = *((const LV *)(const char *)&Data);
- return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
+ return llvm::ArrayRef(LVal.getPath(), LVal.PathLength);
}
unsigned APValue::getLValueCallIndex() const {
@@ -991,7 +1068,7 @@ ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
assert(isMemberPointer() && "Invalid accessor");
const MemberPointerData &MPD =
*((const MemberPointerData *)(const char *)&Data);
- return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
+ return llvm::ArrayRef(MPD.getPath(), MPD.PathLength);
}
void APValue::MakeLValue() {
@@ -1038,7 +1115,7 @@ LinkageInfo LinkageComputer::getLVForValue(const APValue &V,
auto MergeLV = [&](LinkageInfo MergeLV) {
LV.merge(MergeLV);
- return LV.getLinkage() == InternalLinkage;
+ return LV.getLinkage() == Linkage::Internal;
};
auto Merge = [&](const APValue &V) {
return MergeLV(getLVForValue(V, computation));