blob: 38a89aa99ed05ba65da68d27fa8a38b6e88c6387 [file] [log] [blame]
Chris Lattner64c34f12008-11-16 07:46:48 +00001//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the APValue class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/APValue.h"
15#include "llvm/Support/raw_ostream.h"
16using namespace clang;
17
18
19const APValue &APValue::operator=(const APValue &RHS) {
20 if (Kind != RHS.Kind) {
21 MakeUninit();
22 if (RHS.isInt())
23 MakeInt();
24 else if (RHS.isFloat())
25 MakeFloat();
26 else if (RHS.isComplexInt())
27 MakeComplexInt();
28 else if (RHS.isComplexFloat())
29 MakeComplexFloat();
30 else if (RHS.isLValue())
31 MakeLValue();
32 }
33 if (isInt())
34 setInt(RHS.getInt());
35 else if (isFloat())
36 setFloat(RHS.getFloat());
37 else if (isComplexInt())
38 setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
39 else if (isComplexFloat())
40 setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
41 else if (isLValue())
42 setLValue(RHS.getLValueBase(), RHS.getLValueOffset());
43 return *this;
44}
45
46void APValue::MakeUninit() {
47 if (Kind == Int)
48 ((APSInt*)(void*)Data)->~APSInt();
49 else if (Kind == Float)
50 ((APFloat*)(void*)Data)->~APFloat();
51 else if (Kind == ComplexInt)
52 ((ComplexAPSInt*)(void*)Data)->~ComplexAPSInt();
53 else if (Kind == ComplexFloat)
54 ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat();
55 else if (Kind == LValue) {
56 ((LV*)(void*)Data)->~LV();
57 }
58}
59
60void APValue::dump() const {
61 print(llvm::errs());
62 llvm::errs() << '\n';
63 llvm::errs().flush();
64}
65
66static double GetApproxValue(const llvm::APFloat &F) {
67 llvm::APFloat V = F;
68 bool ignored;
69 V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
70 &ignored);
71 return V.convertToDouble();
72}
73
74void APValue::print(llvm::raw_ostream &OS) const {
75 switch (getKind()) {
76 default: assert(0 && "Unknown APValue kind!");
77 case Uninitialized:
78 OS << "Uninitialized";
79 return;
80 case Int:
81 OS << "Int: " << getInt();
82 return;
83 case Float:
84 OS << "Float: " << GetApproxValue(getFloat());
85 return;
86 case ComplexInt:
87 OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
88 return;
89 case ComplexFloat:
90 OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
91 << ", " << GetApproxValue(getComplexFloatImag());
92 case LValue:
93 OS << "LValue: <todo>";
94 return;
95 }
96}
97