aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/APValue.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-15 02:18:13 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-15 02:18:13 +0000
commit83587db1bda97f45d2b5a4189e584e2a18be511a (patch)
treece60b67476bb535994126ecd8ff1ba2a85f00000 /lib/AST/APValue.cpp
parent1d6cc6a44182ef03a373ecd61505042eca3af906 (diff)
Implement DR1454. This allows all intermediate results in constant expressions
to be core constant expressions (including pointers and references to temporaries), and makes constexpr calculations Turing-complete. A Turing machine simulator is included as a testcase. This opens up the possibilty of removing CCValue entirely, and removing some copies from the constant evaluator in the process, but that cleanup is not part of this change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150557 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/APValue.cpp')
-rw-r--r--lib/AST/APValue.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index b8942c3310..4e17d3b69e 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -28,6 +28,7 @@ namespace {
llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
CharUnits Offset;
unsigned PathLength;
+ unsigned CallIndex;
};
}
@@ -166,9 +167,10 @@ const APValue &APValue::operator=(const APValue &RHS) {
else if (isLValue()) {
if (RHS.hasLValuePath())
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
- RHS.isLValueOnePastTheEnd());
+ RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
else
- setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath());
+ setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
+ RHS.getLValueCallIndex());
} else if (isArray()) {
for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
@@ -525,22 +527,31 @@ ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
}
-void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath) {
+unsigned APValue::getLValueCallIndex() const {
+ assert(isLValue() && "Invalid accessor");
+ return ((const LV*)(const char*)Data)->CallIndex;
+}
+
+void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+ unsigned CallIndex) {
assert(isLValue() && "Invalid accessor");
LV &LVal = *((LV*)(char*)Data);
LVal.BaseAndIsOnePastTheEnd.setPointer(B);
LVal.BaseAndIsOnePastTheEnd.setInt(false);
LVal.Offset = O;
+ LVal.CallIndex = CallIndex;
LVal.resizePath((unsigned)-1);
}
void APValue::setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd) {
+ ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
+ unsigned CallIndex) {
assert(isLValue() && "Invalid accessor");
LV &LVal = *((LV*)(char*)Data);
LVal.BaseAndIsOnePastTheEnd.setPointer(B);
LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
LVal.Offset = O;
+ LVal.CallIndex = CallIndex;
LVal.resizePath(Path.size());
memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
}