aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h7
-rw-r--r--include/clang/Basic/Diagnostic.h1
-rw-r--r--include/clang/Basic/PartialDiagnostic.h150
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--lib/Basic/Diagnostic.cpp4
5 files changed, 86 insertions, 82 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 6a7b7d90e5..870c8bb040 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -49,6 +49,7 @@ namespace clang {
class ExternalASTSource;
class ASTMutationListener;
class IdentifierTable;
+ class PartialDiagnosticStorageAllocator;
class SelectorTable;
class SourceManager;
class TargetInfo;
@@ -346,7 +347,7 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
mutable llvm::BumpPtrAllocator BumpAlloc;
/// \brief Allocator for partial diagnostics.
- PartialDiagnostic::StorageAllocator DiagAllocator;
+ PartialDiagnosticStorageAllocator *DiagAllocator;
/// \brief The current C++ ABI.
llvm::OwningPtr<CXXABI> ABI;
@@ -391,8 +392,8 @@ public:
/// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const;
- PartialDiagnostic::StorageAllocator &getDiagAllocator() {
- return DiagAllocator;
+ PartialDiagnosticStorageAllocator &getDiagAllocator() {
+ return *DiagAllocator;
}
const TargetInfo &getTargetInfo() const { return *Target; }
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 8cb1e19940..e5dff5ad09 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -593,6 +593,7 @@ private:
friend class DiagnosticBuilder;
friend class Diagnostic;
friend class PartialDiagnostic;
+ friend struct PartialDiagnosticStorage;
friend class DiagnosticErrorTrap;
/// CurDiagLoc - This is the location of the current diagnostic that is in
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index f6092e6858..7bc9f54655 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -23,91 +23,87 @@
namespace clang {
-class PartialDiagnostic {
-public:
+struct PartialDiagnosticStorage {
+ 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 - The maximum number of arguments we can hold. We
+ /// currently only support up to 10 arguments (%0-%9).
+ /// A single diagnostic with more than that almost certainly has to
+ /// be simplified anyway.
MaxArguments = DiagnosticsEngine::MaxArguments
};
- struct Storage {
- Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
-
- enum {
- /// MaxArguments - The maximum number of arguments we can hold. We
- /// currently only support up to 10 arguments (%0-%9).
- /// A single diagnostic with more than that almost certainly has to
- /// be simplified anyway.
- MaxArguments = PartialDiagnostic::MaxArguments
- };
-
- /// NumDiagArgs - This contains the number of entries in Arguments.
- unsigned char NumDiagArgs;
-
- /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
- unsigned char NumDiagRanges;
-
- /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
- /// values, with one for each argument. This specifies whether the argument
- /// is in DiagArgumentsStr or in DiagArguments.
- unsigned char DiagArgumentsKind[MaxArguments];
-
- /// DiagArgumentsVal - The values for the various substitution positions.
- /// This is used when the argument is not an std::string. The specific value
- /// is mangled into an intptr_t and the interpretation depends on exactly
- /// what sort of argument kind it is.
- intptr_t DiagArgumentsVal[MaxArguments];
-
- /// \brief The values for the various substitution positions that have
- /// string arguments.
- std::string DiagArgumentsStr[MaxArguments];
-
- /// DiagRanges - The list of ranges added to this diagnostic. It currently
- /// only support 10 ranges, could easily be extended if needed.
- CharSourceRange DiagRanges[10];
-
- /// FixItHints - If valid, provides a hint with some code
- /// to insert, remove, or modify at a particular position.
- SmallVector<FixItHint, 6> FixItHints;
- };
+ /// NumDiagArgs - This contains the number of entries in Arguments.
+ unsigned char NumDiagArgs;
- /// \brief An allocator for Storage objects, which uses a small cache to
- /// objects, used to reduce malloc()/free() traffic for partial diagnostics.
- class StorageAllocator {
- static const unsigned NumCached = 16;
- Storage Cached[NumCached];
- Storage *FreeList[NumCached];
- unsigned NumFreeListEntries;
-
- public:
- StorageAllocator();
- ~StorageAllocator();
-
- /// \brief Allocate new storage.
- Storage *Allocate() {
- if (NumFreeListEntries == 0)
- return new Storage;
-
- Storage *Result = FreeList[--NumFreeListEntries];
- Result->NumDiagArgs = 0;
- Result->NumDiagRanges = 0;
- Result->FixItHints.clear();
- return Result;
- }
+ /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
+ unsigned char NumDiagRanges;
+
+ /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+ /// values, with one for each argument. This specifies whether the argument
+ /// is in DiagArgumentsStr or in DiagArguments.
+ unsigned char DiagArgumentsKind[MaxArguments];
+
+ /// DiagArgumentsVal - The values for the various substitution positions.
+ /// This is used when the argument is not an std::string. The specific value
+ /// is mangled into an intptr_t and the interpretation depends on exactly
+ /// what sort of argument kind it is.
+ intptr_t DiagArgumentsVal[MaxArguments];
+
+ /// \brief The values for the various substitution positions that have
+ /// string arguments.
+ std::string DiagArgumentsStr[MaxArguments];
+
+ /// DiagRanges - The list of ranges added to this diagnostic. It currently
+ /// only support 10 ranges, could easily be extended if needed.
+ CharSourceRange DiagRanges[10];
+
+ /// FixItHints - If valid, provides a hint with some code
+ /// to insert, remove, or modify at a particular position.
+ SmallVector<FixItHint, 6> FixItHints;
+};
- /// \brief Free the given storage object.
- void Deallocate(Storage *S) {
- if (S >= Cached && S <= Cached + NumCached) {
- FreeList[NumFreeListEntries++] = S;
- return;
- }
+/// \brief An allocator for Storage objects, which uses a small cache to
+/// objects, used to reduce malloc()/free() traffic for partial diagnostics.
+class PartialDiagnosticStorageAllocator {
+ static const unsigned NumCached = 16;
+ typedef PartialDiagnosticStorage Storage;
+ Storage Cached[NumCached];
+ Storage *FreeList[NumCached];
+ unsigned NumFreeListEntries;
- delete S;
+public:
+ PartialDiagnosticStorageAllocator();
+ ~PartialDiagnosticStorageAllocator();
+
+ /// \brief Allocate new storage.
+ Storage *Allocate() {
+ if (NumFreeListEntries == 0)
+ return new Storage;
+
+ Storage *Result = FreeList[--NumFreeListEntries];
+ Result->NumDiagArgs = 0;
+ Result->NumDiagRanges = 0;
+ Result->FixItHints.clear();
+ return Result;
+ }
+
+ /// \brief Free the given storage object.
+ void Deallocate(Storage *S) {
+ if (S >= Cached && S <= Cached + NumCached) {
+ FreeList[NumFreeListEntries++] = S;
+ return;
}
- };
+
+ delete S;
+ }
+};
+
+class PartialDiagnostic {
+public:
+ typedef PartialDiagnosticStorage Storage;
+ typedef PartialDiagnosticStorageAllocator StorageAllocator;
private:
// NOTE: Sema assumes that PartialDiagnostic is location-invariant
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index c9af67c8b6..8f9ab719b9 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -241,6 +241,9 @@ ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
LastSDM(0, 0),
UniqueBlockByRefTypeID(0)
{
+ // Create a new allocator for partial diagnostics.
+ DiagAllocator = new (BumpAlloc) PartialDiagnosticStorageAllocator;
+
if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this);
@@ -285,6 +288,9 @@ ASTContext::~ASTContext() {
AEnd = DeclAttrs.end();
A != AEnd; ++A)
A->second->~AttrVec();
+
+ // Destroy the partial diagnostic allocator.
+ DiagAllocator->~PartialDiagnosticStorageAllocator();
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index c330215db1..fc7aaebc59 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -842,13 +842,13 @@ bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
void IgnoringDiagConsumer::anchor() { }
-PartialDiagnostic::StorageAllocator::StorageAllocator() {
+PartialDiagnosticStorageAllocator::PartialDiagnosticStorageAllocator() {
for (unsigned I = 0; I != NumCached; ++I)
FreeList[I] = Cached + I;
NumFreeListEntries = NumCached;
}
-PartialDiagnostic::StorageAllocator::~StorageAllocator() {
+PartialDiagnosticStorageAllocator::~PartialDiagnosticStorageAllocator() {
// Don't assert if we are in a CrashRecovery context, as this
// invariant may be invalidated during a crash.
assert((NumFreeListEntries == NumCached || llvm::CrashRecoveryContext::isRecoveringFromCrash()) && "A partial is on the lamb");