xref: /llvm-project/clang/include/clang/AST/APNumericStorage.h (revision 142f270c279f2576e4618fc0d1121181c7531fdf)
1 //===--- APNumericStorage.h - Store APInt/APFloat in ASTContext -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_AST_APNUMERICSTORAGE_H
10 #define LLVM_CLANG_AST_APNUMERICSTORAGE_H
11 
12 #include "llvm/ADT/APFloat.h"
13 #include "llvm/ADT/APInt.h"
14 
15 namespace clang {
16 class ASTContext;
17 
18 /// Used by IntegerLiteral/FloatingLiteral/EnumConstantDecl to store the
19 /// numeric without leaking memory.
20 ///
21 /// For large floats/integers, APFloat/APInt will allocate memory from the heap
22 /// to represent these numbers.  Unfortunately, when we use a BumpPtrAllocator
23 /// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
24 /// the APFloat/APInt values will never get freed. APNumericStorage uses
25 /// ASTContext's allocator for memory allocation.
26 class APNumericStorage {
27   union {
28     uint64_t VAL;   ///< Used to store the <= 64 bits integer value.
29     uint64_t *pVal; ///< Used to store the >64 bits integer value.
30   };
31   unsigned BitWidth;
32 
hasAllocation()33   bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
34 
35   APNumericStorage(const APNumericStorage &) = delete;
36   void operator=(const APNumericStorage &) = delete;
37 
38 protected:
APNumericStorage()39   APNumericStorage() : VAL(0), BitWidth(0) {}
40 
getIntValue()41   llvm::APInt getIntValue() const {
42     unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
43     if (NumWords > 1)
44       return llvm::APInt(BitWidth, NumWords, pVal);
45     else
46       return llvm::APInt(BitWidth, VAL);
47   }
48   void setIntValue(const ASTContext &C, const llvm::APInt &Val);
49 };
50 
51 class APIntStorage : private APNumericStorage {
52 public:
getValue()53   llvm::APInt getValue() const { return getIntValue(); }
setValue(const ASTContext & C,const llvm::APInt & Val)54   void setValue(const ASTContext &C, const llvm::APInt &Val) {
55     setIntValue(C, Val);
56   }
57 };
58 
59 class APFloatStorage : private APNumericStorage {
60 public:
getValue(const llvm::fltSemantics & Semantics)61   llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
62     return llvm::APFloat(Semantics, getIntValue());
63   }
setValue(const ASTContext & C,const llvm::APFloat & Val)64   void setValue(const ASTContext &C, const llvm::APFloat &Val) {
65     setIntValue(C, Val.bitcastToAPInt());
66   }
67 };
68 
69 } // end namespace clang
70 
71 #endif // LLVM_CLANG_AST_APNUMERICSTORAGE_H
72