summaryrefslogtreecommitdiffstats
path: root/include/clang/Basic/PartialDiagnostic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic/PartialDiagnostic.h')
-rw-r--r--include/clang/Basic/PartialDiagnostic.h410
1 files changed, 0 insertions, 410 deletions
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
deleted file mode 100644
index 53ce95c..0000000
--- a/include/clang/Basic/PartialDiagnostic.h
+++ /dev/null
@@ -1,410 +0,0 @@
-//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Implements a partial diagnostic that can be emitted anwyhere
-/// in a DiagnosticBuilder stream.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
-#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-
-namespace clang {
-
-class PartialDiagnostic {
-public:
- 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) { }
-
- enum {
- /// \brief 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
- };
-
- /// \brief The number of entries in Arguments.
- unsigned char NumDiagArgs;
-
- /// \brief Specifies for each argument whether it is in DiagArgumentsStr
- /// or in DiagArguments.
- unsigned char DiagArgumentsKind[MaxArguments];
-
- /// \brief 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];
-
- /// \brief The list of ranges added to this diagnostic.
- SmallVector<CharSourceRange, 8> DiagRanges;
-
- /// \brief If valid, provides a hint with some code to insert, remove, or
- /// modify at a particular position.
- SmallVector<FixItHint, 6> FixItHints;
- };
-
- /// \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->DiagRanges.clear();
- 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;
- }
- };
-
-private:
- // NOTE: Sema assumes that PartialDiagnostic is location-invariant
- // in the sense that its bits can be safely memcpy'ed and destructed
- // in the new location.
-
- /// \brief The diagnostic ID.
- mutable unsigned DiagID;
-
- /// \brief Storage for args and ranges.
- mutable Storage *DiagStorage;
-
- /// \brief Allocator used to allocate storage for this diagnostic.
- StorageAllocator *Allocator;
-
- /// \brief Retrieve storage for this particular diagnostic.
- Storage *getStorage() const {
- if (DiagStorage)
- return DiagStorage;
-
- if (Allocator)
- DiagStorage = Allocator->Allocate();
- else {
- assert(Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)));
- DiagStorage = new Storage;
- }
- return DiagStorage;
- }
-
- void freeStorage() {
- if (!DiagStorage)
- return;
-
- // The hot path for PartialDiagnostic is when we just used it to wrap an ID
- // (typically so we have the flexibility of passing a more complex
- // diagnostic into the callee, but that does not commonly occur).
- //
- // Split this out into a slow function for silly compilers (*cough*) which
- // can't do decent partial inlining.
- freeStorageSlow();
- }
-
- void freeStorageSlow() {
- if (Allocator)
- Allocator->Deallocate(DiagStorage);
- else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
- delete DiagStorage;
- DiagStorage = nullptr;
- }
-
- void AddSourceRange(const CharSourceRange &R) const {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- DiagStorage->DiagRanges.push_back(R);
- }
-
- void AddFixItHint(const FixItHint &Hint) const {
- if (Hint.isNull())
- return;
-
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- DiagStorage->FixItHints.push_back(Hint);
- }
-
-public:
- struct NullDiagnostic {};
- /// \brief Create a null partial diagnostic, which cannot carry a payload,
- /// and only exists to be swapped with a real partial diagnostic.
- PartialDiagnostic(NullDiagnostic)
- : DiagID(0), DiagStorage(nullptr), Allocator(nullptr) { }
-
- PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
- : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { }
-
- PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator)
- {
- if (Other.DiagStorage) {
- DiagStorage = getStorage();
- *DiagStorage = *Other.DiagStorage;
- }
- }
-
- PartialDiagnostic(PartialDiagnostic &&Other)
- : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
- Allocator(Other.Allocator) {
- Other.DiagStorage = nullptr;
- }
-
- PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
- : DiagID(Other.DiagID), DiagStorage(DiagStorage),
- Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
- {
- if (Other.DiagStorage)
- *this->DiagStorage = *Other.DiagStorage;
- }
-
- PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
- : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator)
- {
- // Copy arguments.
- for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
- if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string)
- AddString(Other.getArgStdStr(I));
- else
- AddTaggedVal(Other.getRawArg(I), Other.getArgKind(I));
- }
-
- // Copy source ranges.
- for (unsigned I = 0, N = Other.getNumRanges(); I != N; ++I)
- AddSourceRange(Other.getRange(I));
-
- // Copy fix-its.
- for (unsigned I = 0, N = Other.getNumFixItHints(); I != N; ++I)
- AddFixItHint(Other.getFixItHint(I));
- }
-
- PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
- DiagID = Other.DiagID;
- if (Other.DiagStorage) {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- *DiagStorage = *Other.DiagStorage;
- } else {
- freeStorage();
- }
-
- return *this;
- }
-
- PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
- freeStorage();
-
- DiagID = Other.DiagID;
- DiagStorage = Other.DiagStorage;
- Allocator = Other.Allocator;
-
- Other.DiagStorage = nullptr;
- return *this;
- }
-
- ~PartialDiagnostic() {
- freeStorage();
- }
-
- void swap(PartialDiagnostic &PD) {
- std::swap(DiagID, PD.DiagID);
- std::swap(DiagStorage, PD.DiagStorage);
- std::swap(Allocator, PD.Allocator);
- }
-
- unsigned getDiagID() const { return DiagID; }
-
- void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
- DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
- }
-
- void AddString(StringRef V) const {
- if (!DiagStorage)
- DiagStorage = getStorage();
-
- assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs]
- = DiagnosticsEngine::ak_std_string;
- DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V;
- }
-
- void Emit(const DiagnosticBuilder &DB) const {
- if (!DiagStorage)
- return;
-
- // Add all arguments.
- for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
- if ((DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]
- == DiagnosticsEngine::ak_std_string)
- DB.AddString(DiagStorage->DiagArgumentsStr[i]);
- else
- DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
- (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
- }
-
- // Add all ranges.
- for (const CharSourceRange &Range : DiagStorage->DiagRanges)
- DB.AddSourceRange(Range);
-
- // Add all fix-its.
- for (const FixItHint &Fix : DiagStorage->FixItHints)
- DB.AddFixItHint(Fix);
- }
-
- void EmitToString(DiagnosticsEngine &Diags,
- SmallVectorImpl<char> &Buf) const {
- // FIXME: It should be possible to render a diagnostic to a string without
- // messing with the state of the diagnostics engine.
- DiagnosticBuilder DB(Diags.Report(getDiagID()));
- Emit(DB);
- DB.FlushCounts();
- Diagnostic(&Diags).FormatDiagnostic(Buf);
- DB.Clear();
- Diags.Clear();
- }
-
- /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID
- /// and removing all of its arguments, ranges, and fix-it hints.
- void Reset(unsigned DiagID = 0) {
- this->DiagID = DiagID;
- freeStorage();
- }
-
- bool hasStorage() const { return DiagStorage != nullptr; }
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- unsigned I) {
- PD.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
- return PD;
- }
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- int I) {
- PD.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const char *S) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(S),
- DiagnosticsEngine::ak_c_string);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- StringRef S) {
-
- PD.AddString(S);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const IdentifierInfo *II) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(II),
- DiagnosticsEngine::ak_identifierinfo);
- return PD;
- }
-
- // Adds a DeclContext to the diagnostic. The enable_if template magic is here
- // so that we only match those arguments that are (statically) DeclContexts;
- // other arguments that derive from DeclContext (e.g., RecordDecls) will not
- // match.
- template<typename T>
- friend inline
- typename std::enable_if<std::is_same<T, DeclContext>::value,
- const PartialDiagnostic &>::type
- operator<<(const PartialDiagnostic &PD, T *DC) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
- DiagnosticsEngine::ak_declcontext);
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- SourceRange R) {
- PD.AddSourceRange(CharSourceRange::getTokenRange(R));
- return PD;
- }
-
- friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const CharSourceRange &R) {
- PD.AddSourceRange(R);
- return PD;
- }
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const FixItHint &Hint) {
- PD.AddFixItHint(Hint);
- return PD;
- }
-
-};
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const PartialDiagnostic &PD) {
- PD.Emit(DB);
- return DB;
-}
-
-/// \brief A partial diagnostic along with the source location where this
-/// diagnostic occurs.
-typedef std::pair<SourceLocation, PartialDiagnostic> PartialDiagnosticAt;
-
-} // end namespace clang
-#endif
OpenPOWER on IntegriCloud