aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/Interp/Pointer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/Pointer.cpp')
-rw-r--r--clang/lib/AST/Interp/Pointer.cpp83
1 files changed, 67 insertions, 16 deletions
diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp
index 00943dc846d3..e979b99b0fdd 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -7,9 +7,14 @@
//===----------------------------------------------------------------------===//
#include "Pointer.h"
+#include "Boolean.h"
+#include "Context.h"
+#include "Floating.h"
#include "Function.h"
+#include "Integral.h"
#include "InterpBlock.h"
#include "PrimType.h"
+#include "Record.h"
using namespace clang;
using namespace clang::interp;
@@ -89,7 +94,7 @@ APValue Pointer::toAPValue() const {
Offset = CharUnits::Zero();
} else {
// Build the lvalue base from the block.
- Descriptor *Desc = getDeclDesc();
+ const Descriptor *Desc = getDeclDesc();
if (auto *VD = Desc->asValueDecl())
Base = VD;
else if (auto *E = Desc->asExpr())
@@ -122,8 +127,8 @@ APValue Pointer::toAPValue() const {
bool IsVirtual = false;
// Create a path entry for the field.
- Descriptor *Desc = Ptr.getFieldDesc();
- if (auto *BaseOrMember = Desc->asDecl()) {
+ const Descriptor *Desc = Ptr.getFieldDesc();
+ if (const auto *BaseOrMember = Desc->asDecl()) {
Path.push_back(APValue::LValuePathEntry({BaseOrMember, IsVirtual}));
Ptr = Ptr.getBase();
continue;
@@ -145,6 +150,13 @@ APValue Pointer::toAPValue() const {
return APValue(Base, Offset, Path, IsOnePastEnd, IsNullPtr);
}
+std::string Pointer::toDiagnosticString(const ASTContext &Ctx) const {
+ if (!Pointee)
+ return "nullptr";
+
+ return toAPValue().getAsString(Ctx, getType());
+}
+
bool Pointer::isInitialized() const {
assert(Pointee && "Cannot check if null pointer was initialized");
const Descriptor *Desc = getFieldDesc();
@@ -152,13 +164,16 @@ bool Pointer::isInitialized() const {
if (Desc->isPrimitiveArray()) {
if (isStatic() && Base == 0)
return true;
- // Primitive array field are stored in a bitset.
- InitMap *Map = getInitMap();
- if (!Map)
+
+ InitMapPtr &IM = getInitMap();
+
+ if (!IM)
return false;
- if (Map == (InitMap *)-1)
+
+ if (IM->first)
return true;
- return Map->isInitialized(getIndex());
+
+ return IM->second->isElementInitialized(getIndex());
}
// Field has its bit in an inline descriptor.
@@ -175,15 +190,20 @@ void Pointer::initialize() const {
if (isStatic() && Base == 0)
return;
- // Primitive array initializer.
- InitMap *&Map = getInitMap();
- if (Map == (InitMap *)-1)
+ InitMapPtr &IM = getInitMap();
+ if (!IM)
+ IM =
+ std::make_pair(false, std::make_shared<InitMap>(Desc->getNumElems()));
+
+ assert(IM);
+
+ // All initialized.
+ if (IM->first)
return;
- if (Map == nullptr)
- Map = InitMap::allocate(Desc->getNumElems());
- if (Map->initialize(getIndex())) {
- free(Map);
- Map = (InitMap *)-1;
+
+ if (IM->second->initializeElement(getIndex())) {
+ IM->first = true;
+ IM->second.reset();
}
return;
}
@@ -210,3 +230,34 @@ bool Pointer::hasSameBase(const Pointer &A, const Pointer &B) {
bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) {
return hasSameBase(A, B) && A.Base == B.Base && A.getFieldDesc()->IsArray;
}
+
+APValue Pointer::toRValue(const Context &Ctx) const {
+ // Primitives.
+ if (getFieldDesc()->isPrimitive()) {
+ PrimType PT = *Ctx.classify(getType());
+ TYPE_SWITCH(PT, return deref<T>().toAPValue());
+ llvm_unreachable("Unhandled PrimType?");
+ }
+
+ APValue Result;
+ // Records.
+ if (getFieldDesc()->isRecord()) {
+ const Record *R = getRecord();
+ Result =
+ APValue(APValue::UninitStruct(), R->getNumBases(), R->getNumFields());
+
+ for (unsigned I = 0; I != R->getNumFields(); ++I) {
+ const Pointer &FieldPtr = this->atField(R->getField(I)->Offset);
+ Result.getStructField(I) = FieldPtr.toRValue(Ctx);
+ }
+
+ for (unsigned I = 0; I != R->getNumBases(); ++I) {
+ const Pointer &BasePtr = this->atField(R->getBase(I)->Offset);
+ Result.getStructBase(I) = BasePtr.toRValue(Ctx);
+ }
+ }
+
+ // TODO: Arrays
+
+ return Result;
+}