xref: /llvm-project/clang/lib/AST/APValue.cpp (revision 981f33b0b6c4bc94fb272c8ecd6458ea2fef509c)
1 //===--- 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"
16 using namespace clang;
17 
18 
19 const 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 
46 void 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 
60 void APValue::dump() const {
61   print(llvm::errs());
62   llvm::errs() << '\n';
63   llvm::errs().flush();
64 }
65 
66 static 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 
74 void 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 
98