[clang] 438a27f - Move code to determine the type of an LValueBase out of ExprConstant and
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 10 13:04:10 PST 2020
Author: Richard Smith
Date: 2020-11-10T13:03:57-08:00
New Revision: 438a27f2e56a9753d4cc8477a1f1c306edc4c885
URL: https://github.com/llvm/llvm-project/commit/438a27f2e56a9753d4cc8477a1f1c306edc4c885
DIFF: https://github.com/llvm/llvm-project/commit/438a27f2e56a9753d4cc8477a1f1c306edc4c885.diff
LOG: Move code to determine the type of an LValueBase out of ExprConstant and
into a member function on LValueBase. NFC.
Added:
Modified:
clang/include/clang/AST/APValue.h
clang/lib/AST/APValue.cpp
clang/lib/AST/ExprConstant.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index 6cda588ffe74..4c063ca00d7b 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -173,6 +173,8 @@ class APValue {
QualType getTypeInfoType() const;
QualType getDynamicAllocType() const;
+ QualType getType() const;
+
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
return !(LHS == RHS);
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index e3fb01574b35..266421ce82e3 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -60,6 +60,51 @@ APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,
return Base;
}
+QualType APValue::LValueBase::getType() const {
+ if (!*this) return QualType();
+ if (const ValueDecl *D = dyn_cast<const ValueDecl*>()) {
+ // FIXME: It's unclear where we're supposed to take the type from, and
+ // this actually matters for arrays of unknown bound. Eg:
+ //
+ // extern int arr[]; void f() { extern int arr[3]; };
+ // constexpr int *p = &arr[1]; // valid?
+ //
+ // For now, we take the most complete type we can find.
+ for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
+ Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
+ QualType T = Redecl->getType();
+ if (!T->isIncompleteArrayType())
+ return T;
+ }
+ return D->getType();
+ }
+
+ if (is<TypeInfoLValue>())
+ return getTypeInfoType();
+
+ if (is<DynamicAllocLValue>())
+ return getDynamicAllocType();
+
+ const Expr *Base = get<const Expr*>();
+
+ // For a materialized temporary, the type of the temporary we materialized
+ // may not be the type of the expression.
+ if (const MaterializeTemporaryExpr *MTE =
+ clang::dyn_cast<MaterializeTemporaryExpr>(Base)) {
+ SmallVector<const Expr *, 2> CommaLHSs;
+ SmallVector<SubobjectAdjustment, 2> Adjustments;
+ const Expr *Temp = MTE->getSubExpr();
+ const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs,
+ Adjustments);
+ // Keep any cv-qualifiers from the reference if we generated a temporary
+ // for it directly. Otherwise use the type after adjustment.
+ if (!Adjustments.empty())
+ return Inner->getType();
+ }
+
+ return Base->getType();
+}
+
unsigned APValue::LValueBase::getCallIndex() const {
return (is<TypeInfoLValue>() || is<DynamicAllocLValue>()) ? 0
: Local.CallIndex;
@@ -685,31 +730,25 @@ void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
else if (isLValueOnePastTheEnd())
Out << "*(&";
- QualType ElemTy;
+ QualType ElemTy = Base.getType();
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
Out << *VD;
- ElemTy = VD->getType();
} else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
TI.print(Out, Ctx.getPrintingPolicy());
- ElemTy = Base.getTypeInfoType();
} else if (DynamicAllocLValue DA = Base.dyn_cast<DynamicAllocLValue>()) {
Out << "{*new "
<< Base.getDynamicAllocType().stream(Ctx.getPrintingPolicy()) << "#"
<< DA.getIndex() << "}";
- ElemTy = Base.getDynamicAllocType();
} else {
const Expr *E = Base.get<const Expr*>();
assert(E != nullptr && "Expecting non-null Expr");
E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
- // FIXME: This is wrong if E is a MaterializeTemporaryExpr with an lvalue
- // adjustment.
- ElemTy = E->getType();
}
ArrayRef<LValuePathEntry> Path = getLValuePath();
const CXXRecordDecl *CastToBase = nullptr;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
- if (ElemTy->getAs<RecordType>()) {
+ if (ElemTy->isRecordType()) {
// The lvalue refers to a class type, so the next path entry is a base
// or member.
const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b824470e00d0..44560c6fd84f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -79,48 +79,7 @@ namespace {
CurrentSourceLocExprScope::SourceLocExprScopeGuard;
static QualType getType(APValue::LValueBase B) {
- if (!B) return QualType();
- if (const ValueDecl *D = B.dyn_cast<const ValueDecl*>()) {
- // FIXME: It's unclear where we're supposed to take the type from, and
- // this actually matters for arrays of unknown bound. Eg:
- //
- // extern int arr[]; void f() { extern int arr[3]; };
- // constexpr int *p = &arr[1]; // valid?
- //
- // For now, we take the array bound from the most recent declaration.
- for (auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
- Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
- QualType T = Redecl->getType();
- if (!T->isIncompleteArrayType())
- return T;
- }
- return D->getType();
- }
-
- if (B.is<TypeInfoLValue>())
- return B.getTypeInfoType();
-
- if (B.is<DynamicAllocLValue>())
- return B.getDynamicAllocType();
-
- const Expr *Base = B.get<const Expr*>();
-
- // For a materialized temporary, the type of the temporary we materialized
- // may not be the type of the expression.
- if (const MaterializeTemporaryExpr *MTE =
- dyn_cast<MaterializeTemporaryExpr>(Base)) {
- SmallVector<const Expr *, 2> CommaLHSs;
- SmallVector<SubobjectAdjustment, 2> Adjustments;
- const Expr *Temp = MTE->getSubExpr();
- const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs,
- Adjustments);
- // Keep any cv-qualifiers from the reference if we generated a temporary
- // for it directly. Otherwise use the type after adjustment.
- if (!Adjustments.empty())
- return Inner->getType();
- }
-
- return Base->getType();
+ return B.getType();
}
/// Get an LValue path entry, which is known to not be an array index, as a
More information about the cfe-commits
mailing list