aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h277
1 files changed, 34 insertions, 243 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h b/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h
index 107d621f0dec..9fb70bff7fee 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h
@@ -31,89 +31,7 @@ namespace clang {
class DeclContext;
class IdentifierInfo;
-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 {
- enum {
- /// 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
- };
-
- /// The number of entries in Arguments.
- unsigned char NumDiagArgs = 0;
-
- /// Specifies for each argument whether it is in DiagArgumentsStr
- /// or in DiagArguments.
- unsigned char DiagArgumentsKind[MaxArguments];
-
- /// 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];
-
- /// The values for the various substitution positions that have
- /// string arguments.
- std::string DiagArgumentsStr[MaxArguments];
-
- /// The list of ranges added to this diagnostic.
- SmallVector<CharSourceRange, 8> DiagRanges;
-
- /// If valid, provides a hint with some code to insert, remove, or
- /// modify at a particular position.
- SmallVector<FixItHint, 6> FixItHints;
-
- Storage() = default;
- };
-
- /// 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();
-
- /// 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;
- }
-
- /// Free the given storage object.
- void Deallocate(Storage *S) {
- if (S >= Cached && S <= Cached + NumCached) {
- FreeList[NumFreeListEntries++] = S;
- return;
- }
-
- delete S;
- }
- };
-
+class PartialDiagnostic : public StreamingDiagnostic {
private:
// NOTE: Sema assumes that PartialDiagnostic is location-invariant
// in the sense that its bits can be safely memcpy'ed and destructed
@@ -121,65 +39,6 @@ private:
/// The diagnostic ID.
mutable unsigned DiagID = 0;
-
- /// Storage for args and ranges.
- mutable Storage *DiagStorage = nullptr;
-
- /// Allocator used to allocate storage for this diagnostic.
- StorageAllocator *Allocator = nullptr;
-
- /// 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 {};
@@ -187,32 +46,53 @@ public:
/// and only exists to be swapped with a real partial diagnostic.
PartialDiagnostic(NullDiagnostic) {}
- PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
- : DiagID(DiagID), Allocator(&Allocator) {}
+ PartialDiagnostic(unsigned DiagID, DiagStorageAllocator &Allocator_)
+ : StreamingDiagnostic(Allocator_), DiagID(DiagID) {}
PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), Allocator(Other.Allocator) {
+ : StreamingDiagnostic(), DiagID(Other.DiagID) {
+ Allocator = Other.Allocator;
if (Other.DiagStorage) {
DiagStorage = getStorage();
*DiagStorage = *Other.DiagStorage;
}
}
- PartialDiagnostic(PartialDiagnostic &&Other)
- : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
- Allocator(Other.Allocator) {
+ template <typename T> const PartialDiagnostic &operator<<(const T &V) const {
+ const StreamingDiagnostic &DB = *this;
+ DB << V;
+ return *this;
+ }
+
+ // It is necessary to limit this to rvalue reference to avoid calling this
+ // function with a bitfield lvalue argument since non-const reference to
+ // bitfield is not allowed.
+ template <typename T, typename = typename std::enable_if<
+ !std::is_lvalue_reference<T>::value>::type>
+ const PartialDiagnostic &operator<<(T &&V) const {
+ const StreamingDiagnostic &DB = *this;
+ DB << std::move(V);
+ return *this;
+ }
+
+ PartialDiagnostic(PartialDiagnostic &&Other) : DiagID(Other.DiagID) {
+ Allocator = Other.Allocator;
+ DiagStorage = Other.DiagStorage;
Other.DiagStorage = nullptr;
}
- PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
- : DiagID(Other.DiagID), DiagStorage(DiagStorage),
- Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0))) {
+ PartialDiagnostic(const PartialDiagnostic &Other,
+ DiagnosticStorage *DiagStorage_)
+ : DiagID(Other.DiagID) {
+ Allocator = reinterpret_cast<DiagStorageAllocator *>(~uintptr_t(0));
+ DiagStorage = DiagStorage_;
if (Other.DiagStorage)
*this->DiagStorage = *Other.DiagStorage;
}
- PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
- : DiagID(Other.getID()), Allocator(&Allocator) {
+ PartialDiagnostic(const Diagnostic &Other, DiagStorageAllocator &Allocator_)
+ : DiagID(Other.getID()) {
+ Allocator = &Allocator_;
// Copy arguments.
for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string)
@@ -255,10 +135,6 @@ public:
return *this;
}
- ~PartialDiagnostic() {
- freeStorage();
- }
-
void swap(PartialDiagnostic &PD) {
std::swap(DiagID, PD.DiagID);
std::swap(DiagStorage, PD.DiagStorage);
@@ -266,27 +142,7 @@ public:
}
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++] = std::string(V);
- }
+ void setDiagID(unsigned ID) { DiagID = ID; }
void Emit(const DiagnosticBuilder &DB) const {
if (!DiagStorage)
@@ -317,7 +173,6 @@ public:
// 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();
@@ -340,70 +195,6 @@ public:
== DiagnosticsEngine::ak_std_string && "Not a string arg");
return DiagStorage->DiagArgumentsStr[I];
}
-
- 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 std::enable_if_t<std::is_same<T, DeclContext>::value,
- const PartialDiagnostic &>
- 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,