[cfe-commits] r52609 - in /cfe/trunk: clang.xcodeproj/project.pbxproj include/clang/AST/APValue.h

Chris Lattner sabre at nondot.org
Sat Jun 21 22:45:54 PDT 2008


Author: lattner
Date: Sun Jun 22 00:45:53 2008
New Revision: 52609

URL: http://llvm.org/viewvc/llvm-project?rev=52609&view=rev
Log:
add a new clang::APValue class at Eli's request.  It is a discriminated
union between [potentially complex] APInt/APFloat.

Added:
    cfe/trunk/include/clang/AST/APValue.h
Modified:
    cfe/trunk/clang.xcodeproj/project.pbxproj

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=52609&r1=52608&r2=52609&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Sun Jun 22 00:45:53 2008
@@ -399,6 +399,7 @@
 		DE5932CE0AD60FF400BC794C /* clang.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = clang.h; path = Driver/clang.h; sourceTree = "<group>"; };
 		DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintParserCallbacks.cpp; path = Driver/PrintParserCallbacks.cpp; sourceTree = "<group>"; };
 		DE5932D00AD60FF400BC794C /* PrintPreprocessedOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintPreprocessedOutput.cpp; path = Driver/PrintPreprocessedOutput.cpp; sourceTree = "<group>"; };
+		DE613EF30E0E148D00B05B79 /* APValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APValue.h; path = clang/AST/APValue.h; sourceTree = "<group>"; };
 		DE67E70A0C020EC500F66BC5 /* SemaType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaType.cpp; path = lib/Sema/SemaType.cpp; sourceTree = "<group>"; };
 		DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaStmt.cpp; path = lib/Sema/SemaStmt.cpp; sourceTree = "<group>"; };
 		DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprCXX.cpp; path = lib/Sema/SemaExprCXX.cpp; sourceTree = "<group>"; };
@@ -768,22 +769,24 @@
 		DEC8D98B0A9433BC00353FCA /* AST */ = {
 			isa = PBXGroup;
 			children = (
-				35EE48AD0E0C4CB200715C54 /* DeclCXX.h */,
-				35EE48AE0E0C4CB200715C54 /* ParentMap.h */,
-				35CEA05A0DF9E82700A41296 /* ExprObjC.h */,
+				DE613EF30E0E148D00B05B79 /* APValue.h */,
 				DEC8D9A30A94346E00353FCA /* AST.h */,
 				35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */,
 				DE75ED280B044DC90020CF81 /* ASTContext.h */,
 				1A72BEAC0D641E9400B085E9 /* Attr.h */,
 				DED676D00B6C786700AAD4A3 /* Builtins.def */,
 				DED676F90B6C797B00AAD4A3 /* Builtins.h */,
+				1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */,
+				1A68BC130D0CADDD001A28C8 /* X86Builtins.def */,
 				DEC63B1B0C7B940600DBF169 /* CFG.h */,
 				DEC8D9900A9433CD00353FCA /* Decl.h */,
 				035611470DA6A45C00D2EF2A /* DeclBase.h */,
 				84AF36A00CB17A3B00C820A5 /* DeclObjC.h */,
+				35EE48AD0E0C4CB200715C54 /* DeclCXX.h */,
 				DE0FCA620A95859D00248FD5 /* Expr.h */,
 				1A30A9E80B93A4C800201A91 /* ExprCXX.h */,
-				1A68BC110D0CADDD001A28C8 /* PPCBuiltins.def */,
+				35CEA05A0DF9E82700A41296 /* ExprObjC.h */,
+				35EE48AE0E0C4CB200715C54 /* ParentMap.h */,
 				3547129D0C88881300B3E1D5 /* PrettyPrinter.h */,
 				DE6951C60C4D1F5D00A5826B /* RecordLayout.h */,
 				DE3452800AEF1B1800DBC861 /* Stmt.h */,
@@ -794,7 +797,6 @@
 				1A68BC120D0CADDD001A28C8 /* TargetBuiltins.h */,
 				35BB2D7A0D1994FA00944DB5 /* TranslationUnit.h */,
 				DE3464210B03040900DBC861 /* Type.h */,
-				1A68BC130D0CADDD001A28C8 /* X86Builtins.def */,
 			);
 			name = AST;
 			sourceTree = "<group>";

Added: cfe/trunk/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=52609&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/APValue.h (added)
+++ cfe/trunk/include/clang/AST/APValue.h Sun Jun 22 00:45:53 2008
@@ -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





More information about the cfe-commits mailing list