Move Storage and StorageAllocator out of the PartialDiagnostic class so we can forward declare them.

Let ASTContext allocate the storage in its BumpPtrAllocator.
This will help us remove ASTContext's depedency on PartialDiagnostic.h soon.

llvm-svn: 149780
This commit is contained in:
Benjamin Kramer 2012-02-04 12:30:46 +00:00
parent 3f85fb2277
commit 728ed3f386
5 changed files with 76 additions and 72 deletions

View File

@ -49,6 +49,7 @@ namespace clang {
class ExternalASTSource; class ExternalASTSource;
class ASTMutationListener; class ASTMutationListener;
class IdentifierTable; class IdentifierTable;
class PartialDiagnosticStorageAllocator;
class SelectorTable; class SelectorTable;
class SourceManager; class SourceManager;
class TargetInfo; class TargetInfo;
@ -346,7 +347,7 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
mutable llvm::BumpPtrAllocator BumpAlloc; mutable llvm::BumpPtrAllocator BumpAlloc;
/// \brief Allocator for partial diagnostics. /// \brief Allocator for partial diagnostics.
PartialDiagnostic::StorageAllocator DiagAllocator; PartialDiagnosticStorageAllocator *DiagAllocator;
/// \brief The current C++ ABI. /// \brief The current C++ ABI.
llvm::OwningPtr<CXXABI> ABI; llvm::OwningPtr<CXXABI> ABI;
@ -391,8 +392,8 @@ public:
/// Return the total memory used for various side tables. /// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const; size_t getSideTableAllocatedMemory() const;
PartialDiagnostic::StorageAllocator &getDiagAllocator() { PartialDiagnosticStorageAllocator &getDiagAllocator() {
return DiagAllocator; return *DiagAllocator;
} }
const TargetInfo &getTargetInfo() const { return *Target; } const TargetInfo &getTargetInfo() const { return *Target; }

View File

@ -593,6 +593,7 @@ private:
friend class DiagnosticBuilder; friend class DiagnosticBuilder;
friend class Diagnostic; friend class Diagnostic;
friend class PartialDiagnostic; friend class PartialDiagnostic;
friend struct PartialDiagnosticStorage;
friend class DiagnosticErrorTrap; friend class DiagnosticErrorTrap;
/// CurDiagLoc - This is the location of the current diagnostic that is in /// CurDiagLoc - This is the location of the current diagnostic that is in

View File

@ -23,25 +23,15 @@
namespace clang { namespace clang {
class PartialDiagnostic { struct PartialDiagnosticStorage {
public: PartialDiagnosticStorage() : NumDiagArgs(0), NumDiagRanges(0) { }
enum {
// The MaxArguments and MaxFixItHints member enum values from
// DiagnosticsEngine are private but DiagnosticsEngine declares
// PartialDiagnostic a friend. These enum values are redeclared
// here so that the nested Storage class below can access them.
MaxArguments = DiagnosticsEngine::MaxArguments
};
struct Storage {
Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
enum { enum {
/// MaxArguments - The maximum number of arguments we can hold. We /// MaxArguments - The maximum number of arguments we can hold. We
/// currently only support up to 10 arguments (%0-%9). /// currently only support up to 10 arguments (%0-%9).
/// A single diagnostic with more than that almost certainly has to /// A single diagnostic with more than that almost certainly has to
/// be simplified anyway. /// be simplified anyway.
MaxArguments = PartialDiagnostic::MaxArguments MaxArguments = DiagnosticsEngine::MaxArguments
}; };
/// NumDiagArgs - This contains the number of entries in Arguments. /// NumDiagArgs - This contains the number of entries in Arguments.
@ -76,15 +66,16 @@ public:
/// \brief An allocator for Storage objects, which uses a small cache to /// \brief An allocator for Storage objects, which uses a small cache to
/// objects, used to reduce malloc()/free() traffic for partial diagnostics. /// objects, used to reduce malloc()/free() traffic for partial diagnostics.
class StorageAllocator { class PartialDiagnosticStorageAllocator {
static const unsigned NumCached = 16; static const unsigned NumCached = 16;
typedef PartialDiagnosticStorage Storage;
Storage Cached[NumCached]; Storage Cached[NumCached];
Storage *FreeList[NumCached]; Storage *FreeList[NumCached];
unsigned NumFreeListEntries; unsigned NumFreeListEntries;
public: public:
StorageAllocator(); PartialDiagnosticStorageAllocator();
~StorageAllocator(); ~PartialDiagnosticStorageAllocator();
/// \brief Allocate new storage. /// \brief Allocate new storage.
Storage *Allocate() { Storage *Allocate() {
@ -109,6 +100,11 @@ public:
} }
}; };
class PartialDiagnostic {
public:
typedef PartialDiagnosticStorage Storage;
typedef PartialDiagnosticStorageAllocator StorageAllocator;
private: private:
// NOTE: Sema assumes that PartialDiagnostic is location-invariant // NOTE: Sema assumes that PartialDiagnostic is location-invariant
// in the sense that its bits can be safely memcpy'ed and destructed // in the sense that its bits can be safely memcpy'ed and destructed

View File

@ -241,6 +241,9 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
LastSDM(0, 0), LastSDM(0, 0),
UniqueBlockByRefTypeID(0) UniqueBlockByRefTypeID(0)
{ {
// Create a new allocator for partial diagnostics.
DiagAllocator = new (BumpAlloc) PartialDiagnosticStorageAllocator;
if (size_reserve > 0) Types.reserve(size_reserve); if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this); TUDecl = TranslationUnitDecl::Create(*this);
@ -285,6 +288,9 @@ ASTContext::~ASTContext() {
AEnd = DeclAttrs.end(); AEnd = DeclAttrs.end();
A != AEnd; ++A) A != AEnd; ++A)
A->second->~AttrVec(); A->second->~AttrVec();
// Destroy the partial diagnostic allocator.
DiagAllocator->~PartialDiagnosticStorageAllocator();
} }
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {

View File

@ -842,13 +842,13 @@ bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
void IgnoringDiagConsumer::anchor() { } void IgnoringDiagConsumer::anchor() { }
PartialDiagnostic::StorageAllocator::StorageAllocator() { PartialDiagnosticStorageAllocator::PartialDiagnosticStorageAllocator() {
for (unsigned I = 0; I != NumCached; ++I) for (unsigned I = 0; I != NumCached; ++I)
FreeList[I] = Cached + I; FreeList[I] = Cached + I;
NumFreeListEntries = NumCached; NumFreeListEntries = NumCached;
} }
PartialDiagnostic::StorageAllocator::~StorageAllocator() { PartialDiagnosticStorageAllocator::~PartialDiagnosticStorageAllocator() {
// Don't assert if we are in a CrashRecovery context, as this // Don't assert if we are in a CrashRecovery context, as this
// invariant may be invalidated during a crash. // invariant may be invalidated during a crash.
assert((NumFreeListEntries == NumCached || llvm::CrashRecoveryContext::isRecoveringFromCrash()) && "A partial is on the lamb"); assert((NumFreeListEntries == NumCached || llvm::CrashRecoveryContext::isRecoveringFromCrash()) && "A partial is on the lamb");