}
}
- void *alloc(size_t Size) {
+ template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
+
+ size_t Size = sizeof(T);
assert(Size < Unit);
assert(Head && Head->Buf);
- uint8_t *P = Head->Buf + Head->Used;
- Head->Used += Size;
+ size_t P = (size_t)Head->Buf + Head->Used;
+ uintptr_t AlignedP =
+ (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
+ uint8_t *PP = (uint8_t *)AlignedP;
+ size_t Adjustment = AlignedP - P;
+
+ Head->Used += Size + Adjustment;
if (Head->Used < Unit)
- return P;
+ return new (PP) T(std::forward<Args>(ConstructorArgs)...);
AllocatorNode *NewHead = new AllocatorNode;
NewHead->Buf = new uint8_t[ArenaAllocator::Unit];
NewHead->Next = Head;
Head = NewHead;
NewHead->Used = Size;
- return NewHead->Buf;
+ return new (NewHead->Buf) T(std::forward<Args>(ConstructorArgs)...);
}
private:
OS << " ";
}
-void *operator new(size_t Size, ArenaAllocator &A) { return A.alloc(Size); }
-
// Storage classes
enum Qualifiers : uint8_t {
Q_None = 0,
namespace {
Type *Type::clone(ArenaAllocator &Arena) const {
- return new (Arena) Type(*this);
+ return Arena.alloc<Type>(*this);
}
// Write the "first half" of a given type.
void Type::outputPost(OutputStream &OS) {}
Type *PointerType::clone(ArenaAllocator &Arena) const {
- return new (Arena) PointerType(*this);
+ return Arena.alloc<PointerType>(*this);
}
void PointerType::outputPre(OutputStream &OS) {
}
Type *FunctionType::clone(ArenaAllocator &Arena) const {
- return new (Arena) FunctionType(*this);
+ return Arena.alloc<FunctionType>(*this);
}
void FunctionType::outputPre(OutputStream &OS) {
}
Type *UdtType::clone(ArenaAllocator &Arena) const {
- return new (Arena) UdtType(*this);
+ return Arena.alloc<UdtType>(*this);
}
void UdtType::outputPre(OutputStream &OS) {
}
Type *ArrayType::clone(ArenaAllocator &Arena) const {
- return new (Arena) ArrayType(*this);
+ return Arena.alloc<ArrayType>(*this);
}
void ArrayType::outputPre(OutputStream &OS) {
void Demangler::parse() {
// MSVC-style mangled symbols must start with '?'.
if (!MangledName.consumeFront("?")) {
- SymbolName = new (Arena) Name;
+ SymbolName = Arena.alloc<Name>();
SymbolName->Str = MangledName;
- SymbolType = new (Arena) Type;
+ SymbolType = Arena.alloc<Type>();
SymbolType->Prim = PrimTy::Unknown;
}
Name *Head = nullptr;
while (!MangledName.consumeFront("@")) {
- Name *Elem = new (Arena) Name;
+ Name *Elem = Arena.alloc<Name>();
assert(!Error);
demangleNamePiece(*Elem, Head == nullptr);
}
Type *Demangler::demangleFunctionEncoding() {
- FunctionType *FTy = new (Arena) FunctionType;
+ FunctionType *FTy = Arena.alloc<FunctionType>();
FTy->Prim = PrimTy::Function;
FTy->FunctionClass = (FuncClass)demangleFunctionClass();
// Reads a primitive type.
Type *Demangler::demangleBasicType() {
- Type *Ty = new (Arena) Type;
+ Type *Ty = Arena.alloc<Type>();
switch (MangledName.popFront()) {
case 'X':
}
UdtType *Demangler::demangleClassType() {
- UdtType *UTy = new (Arena) UdtType;
+ UdtType *UTy = Arena.alloc<UdtType>();
switch (MangledName.popFront()) {
case 'T':
// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
// # the E is required for 64-bit non-static pointers
PointerType *Demangler::demanglePointerType() {
- PointerType *Pointer = new (Arena) PointerType;
+ PointerType *Pointer = Arena.alloc<PointerType>();
Pointer->Quals = Q_None;
switch (MangledName.popFront()) {
}
if (MangledName.consumeFront("6")) {
- FunctionType *FTy = new (Arena) FunctionType;
+ FunctionType *FTy = Arena.alloc<FunctionType>();
FTy->Prim = PrimTy::Function;
FTy->CallConvention = demangleCallingConvention();
return nullptr;
}
- ArrayType *ATy = new (Arena) ArrayType;
+ ArrayType *ATy = Arena.alloc<ArrayType>();
ArrayType *Dim = ATy;
for (int I = 0; I < Dimension; ++I) {
Dim->Prim = PrimTy::Array;
Dim->ArrayDimension = demangleNumber();
- Dim->NextDimension = new (Arena) ArrayType;
+ Dim->NextDimension = Arena.alloc<ArrayType>();
Dim = Dim->NextDimension;
}
}
MangledName = MangledName.dropFront();
- *Current = new (Arena) ParamList;
+ *Current = Arena.alloc<ParamList>();
(*Current)->Current = BackRef[N]->clone(Arena);
Current = &(*Current)->Next;
continue;
size_t ArrayDimension = MangledName.size();
- *Current = new (Arena) ParamList;
+ *Current = Arena.alloc<ParamList>();
(*Current)->Current = demangleType(QualifierMangleMode::Drop);
// Single-letter types are ignored for backreferences because