mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 03:46:06 +00:00
[NFC] Refactor DiagnosticBuilder and PartialDiagnostic
PartialDiagnostic misses some functions compared to DiagnosticBuilder. This patch refactors DiagnosticBuilder and PartialDiagnostic, extracts the common functionality so that the streaming << operators are shared. Differential Revision: https://reviews.llvm.org/D84362
This commit is contained in:
parent
ea693a1627
commit
7e561b62d2
@ -573,7 +573,7 @@ private:
|
||||
mutable llvm::BumpPtrAllocator BumpAlloc;
|
||||
|
||||
/// Allocator for partial diagnostics.
|
||||
PartialDiagnostic::StorageAllocator DiagAllocator;
|
||||
PartialDiagnostic::DiagStorageAllocator DiagAllocator;
|
||||
|
||||
/// The current C++ ABI.
|
||||
std::unique_ptr<CXXABI> ABI;
|
||||
@ -652,7 +652,7 @@ public:
|
||||
/// Return the total memory used for various side tables.
|
||||
size_t getSideTableAllocatedMemory() const;
|
||||
|
||||
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
|
||||
PartialDiagnostic::DiagStorageAllocator &getDiagAllocator() {
|
||||
return DiagAllocator;
|
||||
}
|
||||
|
||||
@ -3096,8 +3096,8 @@ private:
|
||||
};
|
||||
|
||||
/// Insertion operator for diagnostics.
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const ASTContext::SectionInfo &Section);
|
||||
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const ASTContext::SectionInfo &Section);
|
||||
|
||||
/// Utility function for constructing a nullary selector.
|
||||
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
|
||||
|
@ -350,19 +350,12 @@ struct ParsedTargetAttr {
|
||||
|
||||
#include "clang/AST/Attrs.inc"
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const Attr *At) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const Attr *At) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
|
||||
DiagnosticsEngine::ak_attr);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
const Attr *At) {
|
||||
PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
|
||||
DiagnosticsEngine::ak_attr);
|
||||
return PD;
|
||||
}
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -215,8 +215,8 @@ inline CanQualType Type::getCanonicalTypeUnqualified() const {
|
||||
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
CanQualType T) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
CanQualType T) {
|
||||
DB << static_cast<QualType>(T);
|
||||
return DB;
|
||||
}
|
||||
|
@ -4513,14 +4513,8 @@ public:
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending NamedDecl's
|
||||
/// into a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const NamedDecl* ND) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
|
||||
DiagnosticsEngine::ak_nameddecl);
|
||||
return DB;
|
||||
}
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
const NamedDecl* ND) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
|
||||
const NamedDecl *ND) {
|
||||
PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
|
||||
DiagnosticsEngine::ak_nameddecl);
|
||||
return PD;
|
||||
|
@ -4075,11 +4075,8 @@ public:
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
|
||||
/// into a diagnostic with <<.
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
AccessSpecifier AS);
|
||||
|
||||
const PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
|
||||
AccessSpecifier AS);
|
||||
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
AccessSpecifier AS);
|
||||
|
||||
} // namespace clang
|
||||
|
||||
|
@ -811,19 +811,10 @@ private:
|
||||
SourceLocation getEndLocPrivate() const;
|
||||
};
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending DeclarationName's
|
||||
/// into a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
DeclarationName N) {
|
||||
DB.AddTaggedVal(N.getAsOpaqueInteger(),
|
||||
DiagnosticsEngine::ak_declarationname);
|
||||
return DB;
|
||||
}
|
||||
|
||||
/// Insertion operator for partial diagnostics. This allows binding
|
||||
/// DeclarationName's into a partial diagnostic with <<.
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
DeclarationName N) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
|
||||
DeclarationName N) {
|
||||
PD.AddTaggedVal(N.getAsOpaqueInteger(),
|
||||
DiagnosticsEngine::ak_declarationname);
|
||||
return PD;
|
||||
|
@ -100,8 +100,8 @@ private:
|
||||
friend class DependentStoredDeclsMap;
|
||||
|
||||
DependentDiagnostic(const PartialDiagnostic &PDiag,
|
||||
PartialDiagnostic::Storage *Storage)
|
||||
: Diag(PDiag, Storage) {}
|
||||
DiagnosticStorage *Storage)
|
||||
: Diag(PDiag, Storage) {}
|
||||
|
||||
static DependentDiagnostic *Create(ASTContext &Context,
|
||||
DeclContext *Parent,
|
||||
|
@ -519,8 +519,8 @@ public:
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending
|
||||
/// NestedNameSpecifiers into a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
NestedNameSpecifier *NNS) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
NestedNameSpecifier *NNS) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
|
||||
DiagnosticsEngine::ak_nestednamespec);
|
||||
return DB;
|
||||
|
@ -687,8 +687,8 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
|
||||
TemplateArgumentListInfo &List) const;
|
||||
};
|
||||
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const TemplateArgument &Arg);
|
||||
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const TemplateArgument &Arg);
|
||||
|
||||
inline TemplateSpecializationType::iterator
|
||||
TemplateSpecializationType::end() const {
|
||||
|
@ -342,10 +342,8 @@ public:
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending TemplateName's
|
||||
/// into a diagnostic with <<.
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
TemplateName N);
|
||||
const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
TemplateName N);
|
||||
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
TemplateName N);
|
||||
|
||||
/// A structure for storing the information associated with a
|
||||
/// substituted template template parameter.
|
||||
|
@ -7071,55 +7071,28 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
|
||||
return type->getBaseElementTypeUnsafe();
|
||||
return type;
|
||||
}
|
||||
/// Insertion operator for diagnostics. This allows sending address spaces into
|
||||
/// a diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
LangAS AS) {
|
||||
DB.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
|
||||
DiagnosticsEngine::ArgumentKind::ak_addrspace);
|
||||
return DB;
|
||||
}
|
||||
|
||||
/// Insertion operator for partial diagnostics. This allows sending adress
|
||||
/// spaces into a diagnostic with <<.
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
LangAS AS) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
|
||||
LangAS AS) {
|
||||
PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
|
||||
DiagnosticsEngine::ArgumentKind::ak_addrspace);
|
||||
return PD;
|
||||
}
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending Qualifiers into a
|
||||
/// diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
Qualifiers Q) {
|
||||
DB.AddTaggedVal(Q.getAsOpaqueValue(),
|
||||
DiagnosticsEngine::ArgumentKind::ak_qual);
|
||||
return DB;
|
||||
}
|
||||
|
||||
/// Insertion operator for partial diagnostics. This allows sending Qualifiers
|
||||
/// into a diagnostic with <<.
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
Qualifiers Q) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
|
||||
Qualifiers Q) {
|
||||
PD.AddTaggedVal(Q.getAsOpaqueValue(),
|
||||
DiagnosticsEngine::ArgumentKind::ak_qual);
|
||||
return PD;
|
||||
}
|
||||
|
||||
/// Insertion operator for diagnostics. This allows sending QualType's into a
|
||||
/// diagnostic with <<.
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
QualType T) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
|
||||
DiagnosticsEngine::ak_qualtype);
|
||||
return DB;
|
||||
}
|
||||
|
||||
/// Insertion operator for partial diagnostics. This allows sending QualType's
|
||||
/// into a diagnostic with <<.
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
QualType T) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
|
||||
QualType T) {
|
||||
PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
|
||||
DiagnosticsEngine::ak_qualtype);
|
||||
return PD;
|
||||
|
@ -144,6 +144,44 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct DiagnosticStorage {
|
||||
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 = 10
|
||||
};
|
||||
|
||||
/// 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;
|
||||
|
||||
DiagnosticStorage() = default;
|
||||
};
|
||||
|
||||
/// Concrete class used by the front-end to report problems and issues.
|
||||
///
|
||||
/// This massages the diagnostics (e.g. handling things like "report warnings
|
||||
@ -928,38 +966,10 @@ private:
|
||||
/// 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 = 10,
|
||||
MaxArguments = DiagnosticStorage::MaxArguments,
|
||||
};
|
||||
|
||||
/// The number of entries in Arguments.
|
||||
signed char NumDiagArgs;
|
||||
|
||||
/// Specifies whether an argument is in DiagArgumentsStr or
|
||||
/// in DiagArguments.
|
||||
///
|
||||
/// This is an array of ArgumentKind::ArgumentKind enum values, one for each
|
||||
/// argument.
|
||||
unsigned char DiagArgumentsKind[MaxArguments];
|
||||
|
||||
/// Holds the values of each string argument for the current
|
||||
/// diagnostic.
|
||||
///
|
||||
/// This is only used when the corresponding ArgumentKind is ak_std_string.
|
||||
std::string DiagArgumentsStr[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 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, 8> DiagFixItHints;
|
||||
DiagnosticStorage DiagStorage;
|
||||
|
||||
DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
|
||||
bool isPragma = L.isValid();
|
||||
@ -1043,6 +1053,156 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// The streaming interface shared between DiagnosticBuilder and
|
||||
/// PartialDiagnostic. This class is not intended to be constructed directly
|
||||
/// but only as base class of DiagnosticBuilder and PartialDiagnostic builder.
|
||||
///
|
||||
/// Any new type of argument accepted by DiagnosticBuilder and PartialDiagnostic
|
||||
/// should be implemented as a '<<' operator of StreamingDiagnostic, e.g.
|
||||
///
|
||||
/// const StreamingDiagnostic&
|
||||
/// operator<<(const StreamingDiagnostic&, NewArgType);
|
||||
///
|
||||
class StreamingDiagnostic {
|
||||
public:
|
||||
/// An allocator for DiagnosticStorage objects, which uses a small cache to
|
||||
/// objects, used to reduce malloc()/free() traffic for partial diagnostics.
|
||||
class DiagStorageAllocator {
|
||||
static const unsigned NumCached = 16;
|
||||
DiagnosticStorage Cached[NumCached];
|
||||
DiagnosticStorage *FreeList[NumCached];
|
||||
unsigned NumFreeListEntries;
|
||||
|
||||
public:
|
||||
DiagStorageAllocator();
|
||||
~DiagStorageAllocator();
|
||||
|
||||
/// Allocate new storage.
|
||||
DiagnosticStorage *Allocate() {
|
||||
if (NumFreeListEntries == 0)
|
||||
return new DiagnosticStorage;
|
||||
|
||||
DiagnosticStorage *Result = FreeList[--NumFreeListEntries];
|
||||
Result->NumDiagArgs = 0;
|
||||
Result->DiagRanges.clear();
|
||||
Result->FixItHints.clear();
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// Free the given storage object.
|
||||
void Deallocate(DiagnosticStorage *S) {
|
||||
if (S >= Cached && S <= Cached + NumCached) {
|
||||
FreeList[NumFreeListEntries++] = S;
|
||||
return;
|
||||
}
|
||||
|
||||
delete S;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
mutable DiagnosticStorage *DiagStorage = nullptr;
|
||||
|
||||
/// Allocator used to allocate storage for this diagnostic.
|
||||
DiagStorageAllocator *Allocator = nullptr;
|
||||
|
||||
public:
|
||||
/// Retrieve storage for this particular diagnostic.
|
||||
DiagnosticStorage *getStorage() const {
|
||||
if (DiagStorage)
|
||||
return DiagStorage;
|
||||
|
||||
assert(Allocator);
|
||||
DiagStorage = Allocator->Allocate();
|
||||
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)
|
||||
return;
|
||||
Allocator->Deallocate(DiagStorage);
|
||||
DiagStorage = nullptr;
|
||||
}
|
||||
|
||||
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
|
||||
if (!DiagStorage)
|
||||
DiagStorage = getStorage();
|
||||
|
||||
assert(DiagStorage->NumDiagArgs < DiagnosticStorage::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 < DiagnosticStorage::MaxArguments &&
|
||||
"Too many arguments to diagnostic!");
|
||||
DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] =
|
||||
DiagnosticsEngine::ak_std_string;
|
||||
DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = std::string(V);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// Conversion of StreamingDiagnostic to bool always returns \c true.
|
||||
///
|
||||
/// This allows is to be used in boolean error contexts (where \c true is
|
||||
/// used to indicate that an error has occurred), like:
|
||||
/// \code
|
||||
/// return Diag(...);
|
||||
/// \endcode
|
||||
operator bool() const { return true; }
|
||||
|
||||
protected:
|
||||
StreamingDiagnostic() = default;
|
||||
|
||||
/// Construct with an external storage not owned by itself. The allocator
|
||||
/// is a null pointer in this case.
|
||||
explicit StreamingDiagnostic(DiagnosticStorage *Storage)
|
||||
: DiagStorage(Storage) {}
|
||||
|
||||
/// Construct with a storage allocator which will manage the storage. The
|
||||
/// allocator is not a null pointer in this case.
|
||||
explicit StreamingDiagnostic(DiagStorageAllocator &Alloc)
|
||||
: Allocator(&Alloc) {}
|
||||
|
||||
StreamingDiagnostic(const StreamingDiagnostic &Diag) = default;
|
||||
StreamingDiagnostic(StreamingDiagnostic &&Diag) = default;
|
||||
|
||||
~StreamingDiagnostic() { freeStorage(); }
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DiagnosticBuilder
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1059,12 +1219,11 @@ public:
|
||||
/// This ensures that compilers with somewhat reasonable optimizers will promote
|
||||
/// the common fields to registers, eliminating increments of the NumArgs field,
|
||||
/// for example.
|
||||
class DiagnosticBuilder {
|
||||
class DiagnosticBuilder : public StreamingDiagnostic {
|
||||
friend class DiagnosticsEngine;
|
||||
friend class PartialDiagnostic;
|
||||
|
||||
mutable DiagnosticsEngine *DiagObj = nullptr;
|
||||
mutable unsigned NumArgs = 0;
|
||||
|
||||
/// Status variable indicating if this diagnostic is still active.
|
||||
///
|
||||
@ -1080,17 +1239,17 @@ class DiagnosticBuilder {
|
||||
DiagnosticBuilder() = default;
|
||||
|
||||
explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
|
||||
: DiagObj(diagObj), IsActive(true) {
|
||||
: StreamingDiagnostic(&diagObj->DiagStorage), DiagObj(diagObj),
|
||||
IsActive(true) {
|
||||
assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
|
||||
diagObj->DiagRanges.clear();
|
||||
diagObj->DiagFixItHints.clear();
|
||||
assert(DiagStorage &&
|
||||
"DiagnosticBuilder requires a valid DiagnosticStorage!");
|
||||
DiagStorage->NumDiagArgs = 0;
|
||||
DiagStorage->DiagRanges.clear();
|
||||
DiagStorage->FixItHints.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
void FlushCounts() {
|
||||
DiagObj->NumDiagArgs = NumArgs;
|
||||
}
|
||||
|
||||
/// Clear out the current diagnostic.
|
||||
void Clear() const {
|
||||
DiagObj = nullptr;
|
||||
@ -1113,10 +1272,6 @@ protected:
|
||||
// (or by a subclass, as in SemaDiagnosticBuilder).
|
||||
if (!isActive()) return false;
|
||||
|
||||
// When emitting diagnostics, we set the final argument count into
|
||||
// the DiagnosticsEngine object.
|
||||
FlushCounts();
|
||||
|
||||
// Process the diagnostic.
|
||||
bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
|
||||
|
||||
@ -1131,18 +1286,35 @@ public:
|
||||
/// input and neuters it.
|
||||
DiagnosticBuilder(const DiagnosticBuilder &D) {
|
||||
DiagObj = D.DiagObj;
|
||||
DiagStorage = D.DiagStorage;
|
||||
IsActive = D.IsActive;
|
||||
IsForceEmit = D.IsForceEmit;
|
||||
D.Clear();
|
||||
NumArgs = D.NumArgs;
|
||||
}
|
||||
|
||||
template <typename T> const DiagnosticBuilder &operator<<(const T &V) const {
|
||||
assert(isActive() && "Clients must not add to cleared diagnostic!");
|
||||
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 DiagnosticBuilder &operator<<(T &&V) const {
|
||||
assert(isActive() && "Clients must not add to cleared diagnostic!");
|
||||
const StreamingDiagnostic &DB = *this;
|
||||
DB << std::move(V);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
|
||||
|
||||
/// Emits the diagnostic.
|
||||
~DiagnosticBuilder() {
|
||||
Emit();
|
||||
}
|
||||
~DiagnosticBuilder() { Emit(); }
|
||||
|
||||
/// Forces the diagnostic to be emitted.
|
||||
const DiagnosticBuilder &setForceEmit() const {
|
||||
@ -1150,42 +1322,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Conversion of DiagnosticBuilder to bool always returns \c true.
|
||||
///
|
||||
/// This allows is to be used in boolean error contexts (where \c true is
|
||||
/// used to indicate that an error has occurred), like:
|
||||
/// \code
|
||||
/// return Diag(...);
|
||||
/// \endcode
|
||||
operator bool() const { return true; }
|
||||
|
||||
void AddString(StringRef S) const {
|
||||
assert(isActive() && "Clients must not add to cleared diagnostic!");
|
||||
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
|
||||
"Too many arguments to diagnostic!");
|
||||
DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
|
||||
DiagObj->DiagArgumentsStr[NumArgs++] = std::string(S);
|
||||
}
|
||||
|
||||
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
|
||||
assert(isActive() && "Clients must not add to cleared diagnostic!");
|
||||
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
|
||||
"Too many arguments to diagnostic!");
|
||||
DiagObj->DiagArgumentsKind[NumArgs] = Kind;
|
||||
DiagObj->DiagArgumentsVal[NumArgs++] = V;
|
||||
}
|
||||
|
||||
void AddSourceRange(const CharSourceRange &R) const {
|
||||
assert(isActive() && "Clients must not add to cleared diagnostic!");
|
||||
DiagObj->DiagRanges.push_back(R);
|
||||
}
|
||||
|
||||
void AddFixItHint(const FixItHint &Hint) const {
|
||||
assert(isActive() && "Clients must not add to cleared diagnostic!");
|
||||
if (!Hint.isNull())
|
||||
DiagObj->DiagFixItHints.push_back(Hint);
|
||||
}
|
||||
|
||||
void addFlagValue(StringRef V) const { DiagObj->FlagValue = std::string(V); }
|
||||
};
|
||||
|
||||
@ -1205,20 +1341,21 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
StringRef S) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
StringRef S) {
|
||||
DB.AddString(S);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const char *Str) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const char *Str) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
|
||||
DiagnosticsEngine::ak_c_string);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
int I) {
|
||||
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
|
||||
return DB;
|
||||
}
|
||||
@ -1226,26 +1363,27 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
|
||||
// We use enable_if here to prevent that this overload is selected for
|
||||
// pointers or other arguments that are implicitly convertible to bool.
|
||||
template <typename T>
|
||||
inline std::enable_if_t<std::is_same<T, bool>::value, const DiagnosticBuilder &>
|
||||
operator<<(const DiagnosticBuilder &DB, T I) {
|
||||
inline std::enable_if_t<std::is_same<T, bool>::value,
|
||||
const StreamingDiagnostic &>
|
||||
operator<<(const StreamingDiagnostic &DB, T I) {
|
||||
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
unsigned I) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
unsigned I) {
|
||||
DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
tok::TokenKind I) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
tok::TokenKind I) {
|
||||
DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const IdentifierInfo *II) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const IdentifierInfo *II) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
|
||||
DiagnosticsEngine::ak_identifierinfo);
|
||||
return DB;
|
||||
@ -1258,63 +1396,64 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
template <typename T>
|
||||
inline std::enable_if_t<
|
||||
std::is_same<std::remove_const_t<T>, DeclContext>::value,
|
||||
const DiagnosticBuilder &>
|
||||
operator<<(const DiagnosticBuilder &DB, T *DC) {
|
||||
const StreamingDiagnostic &>
|
||||
operator<<(const StreamingDiagnostic &DB, T *DC) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
|
||||
DiagnosticsEngine::ak_declcontext);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
SourceRange R) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
SourceRange R) {
|
||||
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
ArrayRef<SourceRange> Ranges) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
ArrayRef<SourceRange> Ranges) {
|
||||
for (SourceRange R : Ranges)
|
||||
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const CharSourceRange &R) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const CharSourceRange &R) {
|
||||
DB.AddSourceRange(R);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const FixItHint &Hint) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const FixItHint &Hint) {
|
||||
DB.AddFixItHint(Hint);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
ArrayRef<FixItHint> Hints) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
ArrayRef<FixItHint> Hints) {
|
||||
for (const FixItHint &Hint : Hints)
|
||||
DB.AddFixItHint(Hint);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &
|
||||
operator<<(const DiagnosticBuilder &DB,
|
||||
inline const StreamingDiagnostic &
|
||||
operator<<(const StreamingDiagnostic &DB,
|
||||
const llvm::Optional<SourceRange> &Opt) {
|
||||
if (Opt)
|
||||
DB << *Opt;
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &
|
||||
operator<<(const DiagnosticBuilder &DB,
|
||||
inline const StreamingDiagnostic &
|
||||
operator<<(const StreamingDiagnostic &DB,
|
||||
const llvm::Optional<CharSourceRange> &Opt) {
|
||||
if (Opt)
|
||||
DB << *Opt;
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &
|
||||
operator<<(const DiagnosticBuilder &DB, const llvm::Optional<FixItHint> &Opt) {
|
||||
inline const StreamingDiagnostic &
|
||||
operator<<(const StreamingDiagnostic &DB,
|
||||
const llvm::Optional<FixItHint> &Opt) {
|
||||
if (Opt)
|
||||
DB << *Opt;
|
||||
return DB;
|
||||
@ -1324,8 +1463,8 @@ operator<<(const DiagnosticBuilder &DB, const llvm::Optional<FixItHint> &Opt) {
|
||||
/// context-sensitive keyword.
|
||||
using DiagNullabilityKind = std::pair<NullabilityKind, bool>;
|
||||
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
DiagNullabilityKind nullability);
|
||||
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
DiagNullabilityKind nullability);
|
||||
|
||||
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
|
||||
unsigned DiagID) {
|
||||
@ -1337,8 +1476,8 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
|
||||
return DiagnosticBuilder(this);
|
||||
}
|
||||
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
llvm::Error &&E);
|
||||
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
llvm::Error &&E);
|
||||
|
||||
inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
|
||||
return Report(SourceLocation(), DiagID);
|
||||
@ -1366,7 +1505,7 @@ public:
|
||||
bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
|
||||
SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
|
||||
|
||||
unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
|
||||
unsigned getNumArgs() const { return DiagObj->DiagStorage.NumDiagArgs; }
|
||||
|
||||
/// Return the kind of the specified index.
|
||||
///
|
||||
@ -1376,7 +1515,8 @@ public:
|
||||
/// \pre Idx < getNumArgs()
|
||||
DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
|
||||
assert(Idx < getNumArgs() && "Argument index out of range!");
|
||||
return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
|
||||
return (DiagnosticsEngine::ArgumentKind)
|
||||
DiagObj->DiagStorage.DiagArgumentsKind[Idx];
|
||||
}
|
||||
|
||||
/// Return the provided argument string specified by \p Idx.
|
||||
@ -1384,7 +1524,7 @@ public:
|
||||
const std::string &getArgStdStr(unsigned Idx) const {
|
||||
assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
|
||||
"invalid argument accessor!");
|
||||
return DiagObj->DiagArgumentsStr[Idx];
|
||||
return DiagObj->DiagStorage.DiagArgumentsStr[Idx];
|
||||
}
|
||||
|
||||
/// Return the specified C string argument.
|
||||
@ -1392,7 +1532,8 @@ public:
|
||||
const char *getArgCStr(unsigned Idx) const {
|
||||
assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
|
||||
"invalid argument accessor!");
|
||||
return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
|
||||
return reinterpret_cast<const char *>(
|
||||
DiagObj->DiagStorage.DiagArgumentsVal[Idx]);
|
||||
}
|
||||
|
||||
/// Return the specified signed integer argument.
|
||||
@ -1400,7 +1541,7 @@ public:
|
||||
int getArgSInt(unsigned Idx) const {
|
||||
assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
|
||||
"invalid argument accessor!");
|
||||
return (int)DiagObj->DiagArgumentsVal[Idx];
|
||||
return (int)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
|
||||
}
|
||||
|
||||
/// Return the specified unsigned integer argument.
|
||||
@ -1408,7 +1549,7 @@ public:
|
||||
unsigned getArgUInt(unsigned Idx) const {
|
||||
assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
|
||||
"invalid argument accessor!");
|
||||
return (unsigned)DiagObj->DiagArgumentsVal[Idx];
|
||||
return (unsigned)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
|
||||
}
|
||||
|
||||
/// Return the specified IdentifierInfo argument.
|
||||
@ -1416,7 +1557,8 @@ public:
|
||||
const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
|
||||
assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
|
||||
"invalid argument accessor!");
|
||||
return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
|
||||
return reinterpret_cast<IdentifierInfo *>(
|
||||
DiagObj->DiagStorage.DiagArgumentsVal[Idx]);
|
||||
}
|
||||
|
||||
/// Return the specified non-string argument in an opaque form.
|
||||
@ -1424,36 +1566,36 @@ public:
|
||||
intptr_t getRawArg(unsigned Idx) const {
|
||||
assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
|
||||
"invalid argument accessor!");
|
||||
return DiagObj->DiagArgumentsVal[Idx];
|
||||
return DiagObj->DiagStorage.DiagArgumentsVal[Idx];
|
||||
}
|
||||
|
||||
/// Return the number of source ranges associated with this diagnostic.
|
||||
unsigned getNumRanges() const {
|
||||
return DiagObj->DiagRanges.size();
|
||||
return DiagObj->DiagStorage.DiagRanges.size();
|
||||
}
|
||||
|
||||
/// \pre Idx < getNumRanges()
|
||||
const CharSourceRange &getRange(unsigned Idx) const {
|
||||
assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
|
||||
return DiagObj->DiagRanges[Idx];
|
||||
return DiagObj->DiagStorage.DiagRanges[Idx];
|
||||
}
|
||||
|
||||
/// Return an array reference for this diagnostic's ranges.
|
||||
ArrayRef<CharSourceRange> getRanges() const {
|
||||
return DiagObj->DiagRanges;
|
||||
return DiagObj->DiagStorage.DiagRanges;
|
||||
}
|
||||
|
||||
unsigned getNumFixItHints() const {
|
||||
return DiagObj->DiagFixItHints.size();
|
||||
return DiagObj->DiagStorage.FixItHints.size();
|
||||
}
|
||||
|
||||
const FixItHint &getFixItHint(unsigned Idx) const {
|
||||
assert(Idx < getNumFixItHints() && "Invalid index!");
|
||||
return DiagObj->DiagFixItHints[Idx];
|
||||
return DiagObj->DiagStorage.FixItHints[Idx];
|
||||
}
|
||||
|
||||
ArrayRef<FixItHint> getFixItHints() const {
|
||||
return DiagObj->DiagFixItHints;
|
||||
return DiagObj->DiagStorage.FixItHints;
|
||||
}
|
||||
|
||||
/// Format this diagnostic into a string, substituting the
|
||||
|
@ -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,52 @@ 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) {
|
||||
PartialDiagnostic(const PartialDiagnostic &Other) : 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 +134,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
~PartialDiagnostic() {
|
||||
freeStorage();
|
||||
}
|
||||
|
||||
void swap(PartialDiagnostic &PD) {
|
||||
std::swap(DiagID, PD.DiagID);
|
||||
std::swap(DiagStorage, PD.DiagStorage);
|
||||
@ -267,27 +142,6 @@ 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 Emit(const DiagnosticBuilder &DB) const {
|
||||
if (!DiagStorage)
|
||||
return;
|
||||
@ -317,7 +171,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 +193,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,
|
||||
|
@ -57,21 +57,16 @@ public:
|
||||
/// The target is the base class.
|
||||
enum BaseNonce { Base };
|
||||
|
||||
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
|
||||
MemberNonce _,
|
||||
CXXRecordDecl *NamingClass,
|
||||
DeclAccessPair FoundDecl,
|
||||
QualType BaseObjectType)
|
||||
AccessedEntity(PartialDiagnostic::DiagStorageAllocator &Allocator,
|
||||
MemberNonce _, CXXRecordDecl *NamingClass,
|
||||
DeclAccessPair FoundDecl, QualType BaseObjectType)
|
||||
: Access(FoundDecl.getAccess()), IsMember(true),
|
||||
Target(FoundDecl.getDecl()), NamingClass(NamingClass),
|
||||
BaseObjectType(BaseObjectType), Diag(0, Allocator) {
|
||||
}
|
||||
BaseObjectType(BaseObjectType), Diag(0, Allocator) {}
|
||||
|
||||
AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
|
||||
BaseNonce _,
|
||||
CXXRecordDecl *BaseClass,
|
||||
CXXRecordDecl *DerivedClass,
|
||||
AccessSpecifier Access)
|
||||
AccessedEntity(PartialDiagnostic::DiagStorageAllocator &Allocator,
|
||||
BaseNonce _, CXXRecordDecl *BaseClass,
|
||||
CXXRecordDecl *DerivedClass, AccessSpecifier Access)
|
||||
: Access(Access), IsMember(false), Target(BaseClass),
|
||||
NamingClass(DerivedClass), Diag(0, Allocator) {}
|
||||
|
||||
|
@ -133,14 +133,13 @@ namespace llvm {
|
||||
namespace clang {
|
||||
|
||||
// Basic
|
||||
class DiagnosticBuilder;
|
||||
class StreamingDiagnostic;
|
||||
|
||||
// Determines whether the low bit of the result pointer for the
|
||||
// given UID is always zero. If so, ActionResult will use that bit
|
||||
// for it's "invalid" flag.
|
||||
template<class Ptr>
|
||||
struct IsResultPtrLowBitFree {
|
||||
static const bool value = false;
|
||||
// Determines whether the low bit of the result pointer for the
|
||||
// given UID is always zero. If so, ActionResult will use that bit
|
||||
// for it's "invalid" flag.
|
||||
template <class Ptr> struct IsResultPtrLowBitFree {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
/// ActionResult - This structure is used while parsing/acting on
|
||||
@ -280,8 +279,12 @@ namespace clang {
|
||||
inline StmtResult StmtError() { return StmtResult(true); }
|
||||
inline TypeResult TypeError() { return TypeResult(true); }
|
||||
|
||||
inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
|
||||
inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
|
||||
inline ExprResult ExprError(const StreamingDiagnostic &) {
|
||||
return ExprError();
|
||||
}
|
||||
inline StmtResult StmtError(const StreamingDiagnostic &) {
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
inline ExprResult ExprEmpty() { return ExprResult(false); }
|
||||
inline StmtResult StmtEmpty() { return StmtResult(false); }
|
||||
|
@ -1044,34 +1044,20 @@ enum AttributeDeclKind {
|
||||
ExpectedFunctionWithProtoType,
|
||||
};
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const ParsedAttr &At) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const ParsedAttr &At) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(At.getAttrName()),
|
||||
DiagnosticsEngine::ak_identifierinfo);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
const ParsedAttr &At) {
|
||||
PD.AddTaggedVal(reinterpret_cast<intptr_t>(At.getAttrName()),
|
||||
DiagnosticsEngine::ak_identifierinfo);
|
||||
return PD;
|
||||
}
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
const ParsedAttr *At) {
|
||||
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
|
||||
const ParsedAttr *At) {
|
||||
DB.AddTaggedVal(reinterpret_cast<intptr_t>(At->getAttrName()),
|
||||
DiagnosticsEngine::ak_identifierinfo);
|
||||
return DB;
|
||||
}
|
||||
|
||||
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
|
||||
const ParsedAttr *At) {
|
||||
PD.AddTaggedVal(reinterpret_cast<intptr_t>(At->getAttrName()),
|
||||
DiagnosticsEngine::ak_identifierinfo);
|
||||
return PD;
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
|
||||
|
@ -1487,16 +1487,14 @@ public:
|
||||
// If we aren't active, there is nothing to do.
|
||||
if (!isActive()) return;
|
||||
|
||||
// Otherwise, we need to emit the diagnostic. First flush the underlying
|
||||
// DiagnosticBuilder data, and clear the diagnostic builder itself so it
|
||||
// won't emit the diagnostic in its own destructor.
|
||||
// Otherwise, we need to emit the diagnostic. First clear the diagnostic
|
||||
// builder itself so it won't emit the diagnostic in its own destructor.
|
||||
//
|
||||
// This seems wasteful, in that as written the DiagnosticBuilder dtor will
|
||||
// do its own needless checks to see if the diagnostic needs to be
|
||||
// emitted. However, because we take care to ensure that the builder
|
||||
// objects never escape, a sufficiently smart compiler will be able to
|
||||
// eliminate that code.
|
||||
FlushCounts();
|
||||
Clear();
|
||||
|
||||
// Dispatch to Sema to emit the diagnostic.
|
||||
@ -1511,6 +1509,17 @@ public:
|
||||
BaseDiag << Value;
|
||||
return Diag;
|
||||
}
|
||||
|
||||
// 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 SemaDiagnosticBuilder &operator<<(T &&V) const {
|
||||
const StreamableDiagnosticBase &DB = *this;
|
||||
DB << std::move(V);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// Emit a diagnostic.
|
||||
|
@ -77,7 +77,7 @@ private:
|
||||
/// might operate on.
|
||||
ASTContext *AST = nullptr;
|
||||
/// The allocator for diagnostics.
|
||||
PartialDiagnostic::StorageAllocator DiagStorage;
|
||||
PartialDiagnostic::DiagStorageAllocator DiagStorage;
|
||||
|
||||
// FIXME: Remove when memoized.
|
||||
std::unique_ptr<SelectedASTNode> ASTNodeSelection;
|
||||
|
@ -11299,9 +11299,9 @@ OMPTraitInfo &ASTContext::getNewOMPTraitInfo() {
|
||||
return *OMPTraitInfoVector.back();
|
||||
}
|
||||
|
||||
const DiagnosticBuilder &
|
||||
clang::operator<<(const DiagnosticBuilder &DB,
|
||||
const ASTContext::SectionInfo &Section) {
|
||||
const StreamingDiagnostic &clang::
|
||||
operator<<(const StreamingDiagnostic &DB,
|
||||
const ASTContext::SectionInfo &Section) {
|
||||
if (Section.Decl)
|
||||
return DB << Section.Decl;
|
||||
return DB << "a prior #pragma section";
|
||||
|
@ -2027,9 +2027,9 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
|
||||
|
||||
// Allocate the copy of the PartialDiagnostic via the ASTContext's
|
||||
// BumpPtrAllocator, rather than the ASTContext itself.
|
||||
PartialDiagnostic::Storage *DiagStorage = nullptr;
|
||||
DiagnosticStorage *DiagStorage = nullptr;
|
||||
if (PDiag.hasStorage())
|
||||
DiagStorage = new (C) PartialDiagnostic::Storage;
|
||||
DiagStorage = new (C) DiagnosticStorage;
|
||||
|
||||
auto *DD = new (C) DependentDiagnostic(PDiag, DiagStorage);
|
||||
|
||||
|
@ -3333,12 +3333,7 @@ static const char *getAccessName(AccessSpecifier AS) {
|
||||
llvm_unreachable("Invalid access specifier!");
|
||||
}
|
||||
|
||||
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
AccessSpecifier AS) {
|
||||
return DB << getAccessName(AS);
|
||||
}
|
||||
|
||||
const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &DB,
|
||||
AccessSpecifier AS) {
|
||||
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
|
||||
AccessSpecifier AS) {
|
||||
return DB << getAccessName(AS);
|
||||
}
|
||||
|
@ -448,8 +448,8 @@ SourceRange TemplateArgumentLoc::getSourceRange() const {
|
||||
llvm_unreachable("Invalid TemplateArgument Kind!");
|
||||
}
|
||||
|
||||
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
const TemplateArgument &Arg) {
|
||||
template <typename T>
|
||||
static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
|
||||
switch (Arg.getKind()) {
|
||||
case TemplateArgument::Null:
|
||||
// This is bad, but not as bad as crashing because of argument
|
||||
@ -502,6 +502,11 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
llvm_unreachable("Invalid TemplateArgument Kind!");
|
||||
}
|
||||
|
||||
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
|
||||
const TemplateArgument &Arg) {
|
||||
return DiagTemplateArg(DB, Arg);
|
||||
}
|
||||
|
||||
clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
|
||||
ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
|
||||
SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
|
||||
|
@ -254,8 +254,8 @@ TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
|
||||
}
|
||||
}
|
||||
|
||||
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
TemplateName N) {
|
||||
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
|
||||
TemplateName N) {
|
||||
std::string NameStr;
|
||||
llvm::raw_string_ostream OS(NameStr);
|
||||
LangOptions LO;
|
||||
@ -268,20 +268,6 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
return DB << NameStr;
|
||||
}
|
||||
|
||||
const PartialDiagnostic&clang::operator<<(const PartialDiagnostic &PD,
|
||||
TemplateName N) {
|
||||
std::string NameStr;
|
||||
llvm::raw_string_ostream OS(NameStr);
|
||||
LangOptions LO;
|
||||
LO.CPlusPlus = true;
|
||||
LO.Bool = true;
|
||||
OS << '\'';
|
||||
N.print(OS, PrintingPolicy(LO));
|
||||
OS << '\'';
|
||||
OS.flush();
|
||||
return PD << NameStr;
|
||||
}
|
||||
|
||||
void TemplateName::dump(raw_ostream &OS) const {
|
||||
LangOptions LO; // FIXME!
|
||||
LO.CPlusPlus = true;
|
||||
|
@ -40,8 +40,8 @@
|
||||
|
||||
using namespace clang;
|
||||
|
||||
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
DiagNullabilityKind nullability) {
|
||||
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
|
||||
DiagNullabilityKind nullability) {
|
||||
StringRef string;
|
||||
switch (nullability.first) {
|
||||
case NullabilityKind::NonNull:
|
||||
@ -61,8 +61,8 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
return DB;
|
||||
}
|
||||
|
||||
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
|
||||
llvm::Error &&E) {
|
||||
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
|
||||
llvm::Error &&E) {
|
||||
DB.AddString(toString(std::move(E)));
|
||||
return DB;
|
||||
}
|
||||
@ -482,13 +482,15 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
|
||||
|
||||
CurDiagLoc = storedDiag.getLocation();
|
||||
CurDiagID = storedDiag.getID();
|
||||
NumDiagArgs = 0;
|
||||
DiagStorage.NumDiagArgs = 0;
|
||||
|
||||
DiagRanges.clear();
|
||||
DiagRanges.append(storedDiag.range_begin(), storedDiag.range_end());
|
||||
DiagStorage.DiagRanges.clear();
|
||||
DiagStorage.DiagRanges.append(storedDiag.range_begin(),
|
||||
storedDiag.range_end());
|
||||
|
||||
DiagFixItHints.clear();
|
||||
DiagFixItHints.append(storedDiag.fixit_begin(), storedDiag.fixit_end());
|
||||
DiagStorage.FixItHints.clear();
|
||||
DiagStorage.FixItHints.append(storedDiag.fixit_begin(),
|
||||
storedDiag.fixit_end());
|
||||
|
||||
assert(Client && "DiagnosticConsumer not set!");
|
||||
Level DiagLevel = storedDiag.getLevel();
|
||||
@ -1141,13 +1143,13 @@ bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const {
|
||||
return Target.IncludeInDiagnosticCounts();
|
||||
}
|
||||
|
||||
PartialDiagnostic::StorageAllocator::StorageAllocator() {
|
||||
PartialDiagnostic::DiagStorageAllocator::DiagStorageAllocator() {
|
||||
for (unsigned I = 0; I != NumCached; ++I)
|
||||
FreeList[I] = Cached + I;
|
||||
NumFreeListEntries = NumCached;
|
||||
}
|
||||
|
||||
PartialDiagnostic::StorageAllocator::~StorageAllocator() {
|
||||
PartialDiagnostic::DiagStorageAllocator::~DiagStorageAllocator() {
|
||||
// Don't assert if we are in a CrashRecovery context, as this invariant may
|
||||
// be invalidated during a crash.
|
||||
assert((NumFreeListEntries == NumCached ||
|
||||
|
@ -74,7 +74,7 @@ TEST(DiagnosticTest, fatalsAsError) {
|
||||
TEST(DiagnosticTest, diagnosticError) {
|
||||
DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
|
||||
new IgnoringDiagConsumer());
|
||||
PartialDiagnostic::StorageAllocator Alloc;
|
||||
PartialDiagnostic::DiagStorageAllocator Alloc;
|
||||
llvm::Expected<std::pair<int, int>> Value = DiagnosticError::create(
|
||||
SourceLocation(), PartialDiagnostic(diag::err_cannot_open_file, Alloc)
|
||||
<< "file"
|
||||
|
Loading…
x
Reference in New Issue
Block a user