diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-01-04 23:13:47 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-01-04 23:13:47 +0000 |
commit | fd5e54da2de7954db03d3eba051c28381df5a4a7 (patch) | |
tree | 7ee6eab0ec0cc6b5f2549db6fd3de5ec986ec09c /clang/lib/AST/APValue.cpp | |
parent | 7ac046a2616d71a8a6c2c618fb3b2bcff92c3a7d (diff) | |
download | bcm5719-llvm-fd5e54da2de7954db03d3eba051c28381df5a4a7.tar.gz bcm5719-llvm-fd5e54da2de7954db03d3eba051c28381df5a4a7.zip |
Add an APValue representation for the difference between two address-of-label expressions. Add support to Evaluate and CGExprConstant for generating/handling them. Remove the special-case for such differences in Expr::isConstantInitializer.
With that done, remove a bunch of buggy code from CGExprConstant for handling scalar expressions which is no longer necessary.
Fixes PR11705.
llvm-svn: 147561
Diffstat (limited to 'clang/lib/AST/APValue.cpp')
-rw-r--r-- | clang/lib/AST/APValue.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 2a68341e5a1..b8942c33101 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -149,6 +149,8 @@ const APValue &APValue::operator=(const APValue &RHS) { MakeMemberPointer(RHS.getMemberPointerDecl(), RHS.isMemberPointerToDerivedMember(), RHS.getMemberPointerPath()); + else if (RHS.isAddrLabelDiff()) + MakeAddrLabelDiff(); } if (isInt()) setInt(RHS.getInt()); @@ -177,8 +179,11 @@ const APValue &APValue::operator=(const APValue &RHS) { getStructBase(I) = RHS.getStructBase(I); for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I) getStructField(I) = RHS.getStructField(I); - } else if (isUnion()) + } else if (isUnion()) { setUnion(RHS.getUnionField(), RHS.getUnionValue()); + } else if (isAddrLabelDiff()) { + setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS()); + } return *this; } @@ -203,6 +208,8 @@ void APValue::MakeUninit() { ((UnionData*)(char*)Data)->~UnionData(); else if (Kind == MemberPointer) ((MemberPointerData*)(char*)Data)->~MemberPointerData(); + else if (Kind == AddrLabelDiff) + ((AddrLabelDiffData*)(char*)Data)->~AddrLabelDiffData(); Kind = Uninitialized; } @@ -285,6 +292,9 @@ void APValue::dump(raw_ostream &OS) const { case MemberPointer: OS << "MemberPointer: <todo>"; return; + case AddrLabelDiff: + OS << "AddrLabelDiff: <todo>"; + return; } llvm_unreachable("Unknown APValue kind!"); } @@ -472,6 +482,11 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ } Out << "0"; return; + case APValue::AddrLabelDiff: + Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); + Out << " - "; + Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); + return; } llvm_unreachable("Unknown APValue kind!"); } |