xref: /llvm-project/clang/lib/AST/APValue.cpp (revision 5b5559b272912394b8a92d35bb2e89b8c5dcc582)
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.isVector())
27       MakeVector();
28     else if (RHS.isComplexInt())
29       MakeComplexInt();
30     else if (RHS.isComplexFloat())
31       MakeComplexFloat();
32     else if (RHS.isLValue())
33       MakeLValue();
34   }
35   if (isInt())
36     setInt(RHS.getInt());
37   else if (isFloat())
38     setFloat(RHS.getFloat());
39   else if (isVector())
40     setVector(((Vec*)(char*)RHS.Data)->Elts, RHS.getVectorLength());
41   else if (isComplexInt())
42     setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
43   else if (isComplexFloat())
44     setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
45   else if (isLValue())
46     setLValue(RHS.getLValueBase(), RHS.getLValueOffset());
47   return *this;
48 }
49 
50 void APValue::MakeUninit() {
51   if (Kind == Int)
52     ((APSInt*)(char*)Data)->~APSInt();
53   else if (Kind == Float)
54     ((APFloat*)(char*)Data)->~APFloat();
55   else if (Kind == Vector)
56     ((Vec*)(char*)Data)->~Vec();
57   else if (Kind == ComplexInt)
58     ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
59   else if (Kind == ComplexFloat)
60     ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
61   else if (Kind == LValue) {
62     ((LV*)(char*)Data)->~LV();
63   }
64   Kind = Uninitialized;
65 }
66 
67 void APValue::dump() const {
68   print(llvm::errs());
69   llvm::errs() << '\n';
70 }
71 
72 static double GetApproxValue(const llvm::APFloat &F) {
73   llvm::APFloat V = F;
74   bool ignored;
75   V.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmNearestTiesToEven,
76             &ignored);
77   return V.convertToDouble();
78 }
79 
80 void APValue::print(llvm::raw_ostream &OS) const {
81   switch (getKind()) {
82   default: assert(0 && "Unknown APValue kind!");
83   case Uninitialized:
84     OS << "Uninitialized";
85     return;
86   case Int:
87     OS << "Int: " << getInt();
88     return;
89   case Float:
90     OS << "Float: " << GetApproxValue(getFloat());
91     return;
92   case Vector:
93     OS << "Vector: " << getVectorElt(0);
94     for (unsigned i = 1; i != getVectorLength(); ++i)
95       OS << ", " << getVectorElt(i);
96     return;
97   case ComplexInt:
98     OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
99     return;
100   case ComplexFloat:
101     OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal())
102        << ", " << GetApproxValue(getComplexFloatImag());
103   case LValue:
104     OS << "LValue: <todo>";
105     return;
106   }
107 }
108 
109