Allocate ASTRecordLayout objects using the allocator associated with ASTContext.

This allows them to be allocated using a BumpPtrAllocated
in the common case.

llvm-svn: 97978
This commit is contained in:
Ted Kremenek 2010-03-08 20:56:29 +00:00
parent d3cbaa1ddf
commit c3015a914f
5 changed files with 110 additions and 62 deletions

View File

@ -128,47 +128,24 @@ private:
friend class ASTContext;
friend class ASTRecordLayoutBuilder;
ASTRecordLayout(uint64_t size, unsigned alignment, unsigned datasize,
const uint64_t *fieldoffsets, unsigned fieldcount)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(0) {
if (FieldCount > 0) {
FieldOffsets = new uint64_t[FieldCount];
for (unsigned i = 0; i < FieldCount; ++i)
FieldOffsets[i] = fieldoffsets[i];
}
}
ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
unsigned datasize, const uint64_t *fieldoffsets,
unsigned fieldcount);
// Constructor for C++ records.
ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
ASTRecordLayout(ASTContext &Ctx,
uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
const PrimaryBaseInfo &PrimaryBase,
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
unsigned numvbases)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
if (FieldCount > 0) {
FieldOffsets = new uint64_t[FieldCount];
for (unsigned i = 0; i < FieldCount; ++i)
FieldOffsets[i] = fieldoffsets[i];
}
unsigned numvbases);
CXXInfo->PrimaryBase = PrimaryBase;
CXXInfo->NonVirtualSize = nonvirtualsize;
CXXInfo->NonVirtualAlign = nonvirtualalign;
for (unsigned i = 0; i != numbases; ++i)
CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
for (unsigned i = 0; i != numvbases; ++i)
CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
}
~ASTRecordLayout() {}
~ASTRecordLayout() {
delete [] FieldOffsets;
delete CXXInfo;
}
void Destroy(ASTContext &Ctx);
ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT

View File

@ -78,21 +78,21 @@ ASTContext::~ASTContext() {
// Increment in loop to prevent using deallocated memory.
Deallocate(&*I++);
}
}
for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
// Increment in loop to prevent using deallocated memory.
ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
delete R;
}
for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
// Increment in loop to prevent using deallocated memory.
if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
R->Destroy(*this);
}
for (llvm::DenseMap<const ObjCContainerDecl*,
const ASTRecordLayout*>::iterator
I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
// Increment in loop to prevent using deallocated memory.
ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
delete R;
for (llvm::DenseMap<const ObjCContainerDecl*,
const ASTRecordLayout*>::iterator
I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
// Increment in loop to prevent using deallocated memory.
if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
R->Destroy(*this);
}
}
// Destroy nested-name-specifiers.

View File

@ -4,8 +4,8 @@ add_clang_library(clangAST
APValue.cpp
ASTConsumer.cpp
ASTContext.cpp
ASTImporter.cpp
ASTDiagnostic.cpp
ASTImporter.cpp
AttrImpl.cpp
CXXInheritance.cpp
Decl.cpp
@ -23,6 +23,7 @@ add_clang_library(clangAST
InheritViz.cpp
NestedNameSpecifier.cpp
ParentMap.cpp
RecordLayout.cpp
RecordLayoutBuilder.cpp
Stmt.cpp
StmtDumper.cpp

View File

@ -0,0 +1,69 @@
//===-- RecordLayout.cpp - Layout information for a struct/union -*- 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 RecordLayout interface.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
using namespace clang;
void ASTRecordLayout::Destroy(ASTContext &Ctx) {
if (FieldOffsets)
Ctx.Deallocate(FieldOffsets);
if (CXXInfo)
Ctx.Deallocate(CXXInfo);
this->~ASTRecordLayout();
Ctx.Deallocate(this);
}
ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
unsigned datasize, const uint64_t *fieldoffsets,
unsigned fieldcount)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(0) {
if (FieldCount > 0) {
FieldOffsets = new (Ctx) uint64_t[FieldCount];
for (unsigned i = 0; i < FieldCount; ++i)
FieldOffsets[i] = fieldoffsets[i];
}
}
// Constructor for C++ records.
ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
uint64_t size, unsigned alignment,
uint64_t datasize,
const uint64_t *fieldoffsets,
unsigned fieldcount,
uint64_t nonvirtualsize,
unsigned nonvirtualalign,
const PrimaryBaseInfo &PrimaryBase,
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
unsigned numvbases)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
{
if (FieldCount > 0) {
FieldOffsets = new (Ctx) uint64_t[FieldCount];
for (unsigned i = 0; i < FieldCount; ++i)
FieldOffsets[i] = fieldoffsets[i];
}
CXXInfo->PrimaryBase = PrimaryBase;
CXXInfo->NonVirtualSize = nonvirtualsize;
CXXInfo->NonVirtualAlign = nonvirtualalign;
for (unsigned i = 0; i != numbases; ++i)
CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
for (unsigned i = 0; i != numvbases; ++i)
CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
}

View File

@ -675,9 +675,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Layout(D);
if (!isa<CXXRecordDecl>(D))
return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
Builder.Size,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
// FIXME: This is not always correct. See the part about bitfields at
// http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
@ -690,16 +691,16 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
uint64_t NonVirtualSize =
IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size(),
NonVirtualSize,
Builder.NonVirtualAlignment,
Builder.PrimaryBase,
Builder.Bases.data(),
Builder.Bases.size(),
Builder.VBases.data(),
Builder.VBases.size());
return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
DataSize, Builder.FieldOffsets.data(),
Builder.FieldOffsets.size(),
NonVirtualSize,
Builder.NonVirtualAlignment,
Builder.PrimaryBase,
Builder.Bases.data(),
Builder.Bases.size(),
Builder.VBases.data(),
Builder.VBases.size());
}
const ASTRecordLayout *
@ -710,10 +711,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Layout(D, Impl);
return new ASTRecordLayout(Builder.Size, Builder.Alignment,
Builder.DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
Builder.DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
}
const CXXMethodDecl *