summaryrefslogtreecommitdiff
path: root/include/clang/AST/APValue.h
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-06-22 05:45:53 +0000
committerChris Lattner <sabre@nondot.org>2008-06-22 05:45:53 +0000
commit8031a85dc88225723d960c7c142e4fe97c2f12fe (patch)
tree5e6360f27e477bbbf1253aac546b7b599475dd25 /include/clang/AST/APValue.h
parent27933c17617efe4902a7d4a9f52c751f85a7d92f (diff)
downloadclang-8031a85dc88225723d960c7c142e4fe97c2f12fe.tar.gz
clang-8031a85dc88225723d960c7c142e4fe97c2f12fe.tar.bz2
clang-8031a85dc88225723d960c7c142e4fe97c2f12fe.tar.xz
add a new clang::APValue class at Eli's request. It is a discriminated
union between [potentially complex] APInt/APFloat. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52609 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/APValue.h')
-rw-r--r--include/clang/AST/APValue.h183
1 files changed, 183 insertions, 0 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
new file mode 100644
index 0000000000..22d0cd1fb5
--- /dev/null
+++ b/include/clang/AST/APValue.h
@@ -0,0 +1,183 @@
+//===--- APValue.h - Union class for APFloat/APInt/Complex ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the APValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_APVALUE_H
+#define LLVM_CLANG_AST_APVALUE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APFloat.h"
+
+namespace clang {
+
+/// APValue - This class implements a discriminated union of [uninitialized]
+/// [APInt] [APFloat], [Complex APInt] [Complex APFloat].
+class APValue {
+ typedef llvm::APInt APInt;
+ typedef llvm::APFloat APFloat;
+public:
+ enum ValueKind {
+ Uninitialized,
+ Int,
+ Float,
+ ComplexInt,
+ ComplexFloat
+ };
+private:
+ ValueKind Kind;
+
+ struct ComplexAPInt { APInt Real, Imag; };
+ struct ComplexAPFloat {
+ APFloat Real, Imag;
+ ComplexAPFloat() : Real(0.0), Imag(0.0) {}
+ };
+
+ enum {
+ MaxSize = (sizeof(ComplexAPInt) > sizeof(ComplexAPFloat) ?
+ sizeof(ComplexAPInt) : sizeof(ComplexAPFloat))
+ };
+
+ /// Data - space for the largest member in units of void*. This is an effort
+ /// to ensure that the APInt/APFloat values have proper alignment.
+ void *Data[(MaxSize+sizeof(void*)-1)/sizeof(void*)];
+
+public:
+ APValue() : Kind(Uninitialized) {}
+ explicit APValue(const APInt &I) : Kind(Uninitialized) {
+ MakeInt(); setInt(I);
+ }
+ explicit APValue(const APFloat &F) : Kind(Uninitialized) {
+ MakeFloat(); setFloat(F);
+ }
+ APValue(const APInt &R, const APInt &I) : Kind(Uninitialized) {
+ MakeComplexInt(); setComplexInt(R, I);
+ }
+ APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
+ MakeComplexFloat(); setComplexFloat(R, I);
+ }
+ APValue(const APValue &RHS) : Kind(Uninitialized) {
+ *this = RHS;
+ }
+ ~APValue() {
+ MakeUninit();
+ }
+
+ ValueKind getKind() const { return Kind; }
+ bool isUninit() const { return Kind == Uninitialized; }
+ bool isInt() const { return Kind == Int; }
+ bool isFloat() const { return Kind == Float; }
+ bool isComplexInt() const { return Kind == ComplexInt; }
+ bool isComplexFloat() const { return Kind == ComplexFloat; }
+
+ const APInt &getInt() const {
+ assert(isInt() && "Invalid accessor");
+ return *(const APInt*)(const void*)Data;
+ }
+ const APFloat &getFloat() const {
+ assert(isFloat() && "Invalid accessor");
+ return *(const APFloat*)(const void*)Data;
+ }
+ const APInt &getComplexIntReal() const {
+ assert(isComplexInt() && "Invalid accessor");
+ return ((const ComplexAPInt*)(const void*)Data)->Real;
+ }
+ const APInt &getComplexIntImag() const {
+ assert(isComplexInt() && "Invalid accessor");
+ return ((const ComplexAPInt*)(const void*)Data)->Imag;
+ }
+ const APFloat &getComplexFloatReal() const {
+ assert(isComplexFloat() && "Invalid accessor");
+ return ((const ComplexAPFloat*)(const void*)Data)->Real;
+ }
+ const APFloat &getComplexFloatImag() const {
+ assert(isComplexFloat() && "Invalid accessor");
+ return ((const ComplexAPFloat*)(const void*)Data)->Imag;
+ }
+
+ void setInt(const APInt &I) {
+ assert(isInt() && "Invalid accessor");
+ *(APInt*)(void*)Data = I;
+ }
+ void setFloat(const APFloat &F) {
+ assert(isFloat() && "Invalid accessor");
+ *(APFloat*)(void*)Data = F;
+ }
+ void setComplexInt(const APInt &R, const APInt &I) {
+ assert(isComplexInt() && "Invalid accessor");
+ ((ComplexAPInt*)(void*)Data)->Real = R;
+ ((ComplexAPInt*)(void*)Data)->Imag = I;
+ }
+ void setComplexFloat(const APFloat &R, const APFloat &I) {
+ assert(isComplexFloat() && "Invalid accessor");
+ ((ComplexAPFloat*)(void*)Data)->Real = R;
+ ((ComplexAPFloat*)(void*)Data)->Imag = I;
+ }
+
+ const APValue &operator=(const APValue &RHS) {
+ if (Kind != RHS.Kind) {
+ MakeUninit();
+ if (RHS.isInt())
+ MakeInt();
+ else if (RHS.isFloat())
+ MakeFloat();
+ else if (RHS.isComplexInt())
+ MakeComplexInt();
+ else if (RHS.isComplexFloat())
+ MakeComplexFloat();
+ }
+ if (isInt())
+ setInt(RHS.getInt());
+ else if (isFloat())
+ setFloat(RHS.getFloat());
+ else if (isComplexInt())
+ setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
+ else if (isComplexFloat())
+ setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
+ return *this;
+ }
+
+private:
+ void MakeUninit() {
+ if (Kind == Int)
+ ((APInt*)(void*)Data)->~APInt();
+ else if (Kind == Float)
+ ((APFloat*)(void*)Data)->~APFloat();
+ else if (Kind == ComplexInt)
+ ((ComplexAPInt*)(void*)Data)->~ComplexAPInt();
+ else if (Kind == ComplexFloat)
+ ((ComplexAPFloat*)(void*)Data)->~ComplexAPFloat();
+ }
+ void MakeInt() {
+ assert(isUninit() && "Bad state change");
+ new ((void*)Data) APInt();
+ Kind = Int;
+ }
+ void MakeFloat() {
+ assert(isUninit() && "Bad state change");
+ new ((APFloat*)(void*)Data) APFloat(0.0);
+ Kind = Float;
+ }
+ void MakeComplexInt() {
+ assert(isUninit() && "Bad state change");
+ new ((ComplexAPInt*)(void*)Data) ComplexAPInt();
+ Kind = ComplexInt;
+ }
+ void MakeComplexFloat() {
+ assert(isUninit() && "Bad state change");
+ new ((ComplexAPFloat*)(void*)Data) ComplexAPFloat();
+ Kind = ComplexFloat;
+ }
+};
+
+}
+
+#endif