Recommit [NFC] Refactor DiagnosticBuilder and PartialDiagnostic

This recommits 829d14ee0a.

The patch was reverted due to a regression in some CUDA app
which was thought to be caused by this patch. However, investigation
showed that the regression was due to some other issues, therefore
recommit this patch.
This commit is contained in:
Yaxun (Sam) Liu 2020-09-23 16:16:00 -04:00
parent 2e7117f847
commit 8e780a1653
20 changed files with 182 additions and 256 deletions

View File

@ -3064,8 +3064,9 @@ private:
};
/// Insertion operator for diagnostics.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const ASTContext::SectionInfo &Section);
const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB,
const ASTContext::SectionInfo &Section);
/// Utility function for constructing a nullary selector.
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {

View File

@ -350,19 +350,12 @@ struct ParsedTargetAttr {
#include "clang/AST/Attrs.inc"
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const Attr *At) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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

View File

@ -215,8 +215,8 @@ inline CanQualType Type::getCanonicalTypeUnqualified() const {
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
CanQualType T) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, CanQualType T) {
DB << static_cast<QualType>(T);
return DB;
}

View File

@ -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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &PD, const NamedDecl *ND) {
PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
DiagnosticsEngine::ak_nameddecl);
return PD;

View File

@ -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 StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB,
AccessSpecifier AS);
} // namespace clang

View File

@ -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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &PD, DeclarationName N) {
PD.AddTaggedVal(N.getAsOpaqueInteger(),
DiagnosticsEngine::ak_declarationname);
return PD;

View File

@ -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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, NestedNameSpecifier *NNS) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
DiagnosticsEngine::ak_nestednamespec);
return DB;

View File

@ -687,8 +687,8 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
TemplateArgumentListInfo &List) const;
};
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const TemplateArgument &Arg);
const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB,
const TemplateArgument &Arg);
inline TemplateSpecializationType::iterator
TemplateSpecializationType::end() const {

View File

@ -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 StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB,
TemplateName N);
/// A structure for storing the information associated with a
/// substituted template template parameter.

View File

@ -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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &PD, QualType T) {
PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
DiagnosticsEngine::ak_qualtype);
return PD;

View File

@ -1043,6 +1043,35 @@ public:
}
};
/// The streaming interface shared between DiagnosticBuilder and
/// PartialDiagnostic.
///
/// Any new type of argument accepted by DiagnosticBuilder and PartialDiagnostic
/// should be implemented as a '<<' operator of StreamableDiagnosticBase, e.g.
///
/// const StreamableDiagnosticBase&
/// operator<<(const StreamableDiagnosticBase&, NewArgType);
///
class StreamableDiagnosticBase {
public:
virtual void AddString(StringRef S) const = 0;
virtual void AddTaggedVal(intptr_t V,
DiagnosticsEngine::ArgumentKind Kind) const = 0;
virtual void AddSourceRange(const CharSourceRange &R) const = 0;
virtual void AddFixItHint(const FixItHint &Hint) const = 0;
/// Conversion of StreamableDiagnosticBase 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; }
virtual ~StreamableDiagnosticBase() {}
};
//===----------------------------------------------------------------------===//
// DiagnosticBuilder
//===----------------------------------------------------------------------===//
@ -1059,7 +1088,7 @@ 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 StreamableDiagnosticBase {
friend class DiagnosticsEngine;
friend class PartialDiagnostic;
@ -1137,12 +1166,27 @@ public:
NumArgs = D.NumArgs;
}
template <typename T> const DiagnosticBuilder &operator<<(const T &V) const {
const StreamableDiagnosticBase &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 {
const StreamableDiagnosticBase &DB = *this;
DB << std::move(V);
return *this;
}
DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
/// Emits the diagnostic.
~DiagnosticBuilder() {
Emit();
}
virtual ~DiagnosticBuilder() { Emit(); }
/// Forces the diagnostic to be emitted.
const DiagnosticBuilder &setForceEmit() const {
@ -1150,16 +1194,7 @@ 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 {
void AddString(StringRef S) const override {
assert(isActive() && "Clients must not add to cleared diagnostic!");
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
"Too many arguments to diagnostic!");
@ -1167,7 +1202,8 @@ public:
DiagObj->DiagArgumentsStr[NumArgs++] = std::string(S);
}
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
void AddTaggedVal(intptr_t V,
DiagnosticsEngine::ArgumentKind Kind) const override {
assert(isActive() && "Clients must not add to cleared diagnostic!");
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
"Too many arguments to diagnostic!");
@ -1175,12 +1211,12 @@ public:
DiagObj->DiagArgumentsVal[NumArgs++] = V;
}
void AddSourceRange(const CharSourceRange &R) const {
void AddSourceRange(const CharSourceRange &R) const override {
assert(isActive() && "Clients must not add to cleared diagnostic!");
DiagObj->DiagRanges.push_back(R);
}
void AddFixItHint(const FixItHint &Hint) const {
void AddFixItHint(const FixItHint &Hint) const override {
assert(isActive() && "Clients must not add to cleared diagnostic!");
if (!Hint.isNull())
DiagObj->DiagFixItHints.push_back(Hint);
@ -1205,20 +1241,21 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
StringRef S) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, StringRef S) {
DB.AddString(S);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const char *Str) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, int I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
return DB;
}
@ -1226,26 +1263,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 StreamableDiagnosticBase &>
operator<<(const StreamableDiagnosticBase &DB, T I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
unsigned I) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, unsigned I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
tok::TokenKind I) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, const IdentifierInfo *II) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
DiagnosticsEngine::ak_identifierinfo);
return DB;
@ -1258,63 +1296,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 StreamableDiagnosticBase &>
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, SourceRange R) {
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
ArrayRef<SourceRange> Ranges) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, const CharSourceRange &R) {
DB.AddSourceRange(R);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const FixItHint &Hint) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, const FixItHint &Hint) {
DB.AddFixItHint(Hint);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
ArrayRef<FixItHint> Hints) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB, ArrayRef<FixItHint> Hints) {
for (const FixItHint &Hint : Hints)
DB.AddFixItHint(Hint);
return DB;
}
inline const DiagnosticBuilder &
operator<<(const DiagnosticBuilder &DB,
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB,
const llvm::Optional<SourceRange> &Opt) {
if (Opt)
DB << *Opt;
return DB;
}
inline const DiagnosticBuilder &
operator<<(const DiagnosticBuilder &DB,
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &DB,
const llvm::Optional<FixItHint> &Opt) {
if (Opt)
DB << *Opt;
return DB;
@ -1324,8 +1363,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 StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB,
DiagNullabilityKind nullability);
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
unsigned DiagID) {
@ -1337,8 +1376,8 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
return DiagnosticBuilder(this);
}
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
llvm::Error &&E);
const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB,
llvm::Error &&E);
inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
return Report(SourceLocation(), DiagID);

View File

@ -31,7 +31,7 @@ namespace clang {
class DeclContext;
class IdentifierInfo;
class PartialDiagnostic {
class PartialDiagnostic : public StreamableDiagnosticBase {
public:
enum {
// The MaxArguments and MaxFixItHints member enum values from
@ -163,14 +163,15 @@ private:
DiagStorage = nullptr;
}
void AddSourceRange(const CharSourceRange &R) const {
public:
void AddSourceRange(const CharSourceRange &R) const override {
if (!DiagStorage)
DiagStorage = getStorage();
DiagStorage->DiagRanges.push_back(R);
}
void AddFixItHint(const FixItHint &Hint) const {
void AddFixItHint(const FixItHint &Hint) const override {
if (Hint.isNull())
return;
@ -180,7 +181,6 @@ private:
DiagStorage->FixItHints.push_back(Hint);
}
public:
struct NullDiagnostic {};
/// Create a null partial diagnostic, which cannot carry a payload,
@ -198,6 +198,23 @@ public:
}
}
template <typename T> const PartialDiagnostic &operator<<(const T &V) const {
const StreamableDiagnosticBase &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 StreamableDiagnosticBase &DB = *this;
DB << std::move(V);
return *this;
}
PartialDiagnostic(PartialDiagnostic &&Other)
: DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
Allocator(Other.Allocator) {
@ -255,9 +272,7 @@ public:
return *this;
}
~PartialDiagnostic() {
freeStorage();
}
virtual ~PartialDiagnostic() { freeStorage(); }
void swap(PartialDiagnostic &PD) {
std::swap(DiagID, PD.DiagID);
@ -267,7 +282,8 @@ public:
unsigned getDiagID() const { return DiagID; }
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
void AddTaggedVal(intptr_t V,
DiagnosticsEngine::ArgumentKind Kind) const override {
if (!DiagStorage)
DiagStorage = getStorage();
@ -277,7 +293,7 @@ public:
DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
}
void AddString(StringRef V) const {
void AddString(StringRef V) const override {
if (!DiagStorage)
DiagStorage = getStorage();
@ -340,70 +356,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,

View File

@ -133,7 +133,7 @@ namespace llvm {
namespace clang {
// Basic
class DiagnosticBuilder;
class StreamableDiagnosticBase;
// Determines whether the low bit of the result pointer for the
// given UID is always zero. If so, ActionResult will use that bit
@ -280,8 +280,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 StreamableDiagnosticBase &) {
return ExprError();
}
inline StmtResult StmtError(const StreamableDiagnosticBase &) {
return StmtError();
}
inline ExprResult ExprEmpty() { return ExprResult(false); }
inline StmtResult StmtEmpty() { return StmtResult(false); }

View File

@ -1044,34 +1044,20 @@ enum AttributeDeclKind {
ExpectedFunctionWithProtoType,
};
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const ParsedAttr &At) {
inline const StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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 StreamableDiagnosticBase &
operator<<(const StreamableDiagnosticBase &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

View File

@ -1511,6 +1511,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.

View File

@ -11298,9 +11298,9 @@ OMPTraitInfo &ASTContext::getNewOMPTraitInfo() {
return *OMPTraitInfoVector.back();
}
const DiagnosticBuilder &
clang::operator<<(const DiagnosticBuilder &DB,
const ASTContext::SectionInfo &Section) {
const StreamableDiagnosticBase &clang::
operator<<(const StreamableDiagnosticBase &DB,
const ASTContext::SectionInfo &Section) {
if (Section.Decl)
return DB << Section.Decl;
return DB << "a prior #pragma section";

View File

@ -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 StreamableDiagnosticBase &clang::
operator<<(const StreamableDiagnosticBase &DB, AccessSpecifier AS) {
return DB << getAccessName(AS);
}

View File

@ -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 StreamableDiagnosticBase &clang::
operator<<(const StreamableDiagnosticBase &DB, const TemplateArgument &Arg) {
return DiagTemplateArg(DB, Arg);
}
clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {

View File

@ -254,8 +254,8 @@ TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
}
}
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
TemplateName N) {
const StreamableDiagnosticBase &clang::
operator<<(const StreamableDiagnosticBase &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;

View File

@ -40,8 +40,9 @@
using namespace clang;
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
DiagNullabilityKind nullability) {
const StreamableDiagnosticBase &clang::
operator<<(const StreamableDiagnosticBase &DB,
DiagNullabilityKind nullability) {
StringRef string;
switch (nullability.first) {
case NullabilityKind::NonNull:
@ -61,8 +62,8 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
return DB;
}
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
llvm::Error &&E) {
const StreamableDiagnosticBase &clang::
operator<<(const StreamableDiagnosticBase &DB, llvm::Error &&E) {
DB.AddString(toString(std::move(E)));
return DB;
}