diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 397fee4d866beb..de0d1198b6d40c 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3064,9 +3064,8 @@ OPT_LIST(V) }; /// Insertion operator for diagnostics. -const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, - const ASTContext::SectionInfo &Section); +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const ASTContext::SectionInfo &Section); /// Utility function for constructing a nullary selector. inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) { diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index b4dce8f41c672c..b3729b2e0d995f 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -350,12 +350,19 @@ struct ParsedTargetAttr { #include "clang/AST/Attrs.inc" -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const Attr *At) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const Attr *At) { DB.AddTaggedVal(reinterpret_cast(At), DiagnosticsEngine::ak_attr); return DB; } + +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const Attr *At) { + PD.AddTaggedVal(reinterpret_cast(At), + DiagnosticsEngine::ak_attr); + return PD; +} } // end namespace clang #endif diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index b6d9b69db09afe..488284713bceca 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -215,8 +215,8 @@ inline CanQualType Type::getCanonicalTypeUnqualified() const { return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, CanQualType T) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + CanQualType T) { DB << static_cast(T); return DB; } diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 852ba2316f82bc..c2511514fe7263 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -4513,8 +4513,14 @@ class EmptyDecl : public Decl { /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &PD, const NamedDecl *ND) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const NamedDecl* ND) { + DB.AddTaggedVal(reinterpret_cast(ND), + DiagnosticsEngine::ak_nameddecl); + return DB; +} +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const NamedDecl* ND) { PD.AddTaggedVal(reinterpret_cast(ND), DiagnosticsEngine::ak_nameddecl); return PD; diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 065a7413e7e7d7..20f058b87e7f33 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -4070,8 +4070,11 @@ class MSGuidDecl : public ValueDecl, /// Insertion operator for diagnostics. This allows sending an AccessSpecifier /// into a diagnostic with <<. -const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB, - AccessSpecifier AS); +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + AccessSpecifier AS); + +const PartialDiagnostic &operator<<(const PartialDiagnostic &DB, + AccessSpecifier AS); } // namespace clang diff --git a/clang/include/clang/AST/DeclarationName.h b/clang/include/clang/AST/DeclarationName.h index b5692ec7684bcc..a037e8b197bc35 100644 --- a/clang/include/clang/AST/DeclarationName.h +++ b/clang/include/clang/AST/DeclarationName.h @@ -811,10 +811,19 @@ struct DeclarationNameInfo { 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 StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &PD, DeclarationName N) { +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + DeclarationName N) { PD.AddTaggedVal(N.getAsOpaqueInteger(), DiagnosticsEngine::ak_declarationname); return PD; diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h index 70edcfe7042320..b11cb5f6b86d0b 100644 --- a/clang/include/clang/AST/NestedNameSpecifier.h +++ b/clang/include/clang/AST/NestedNameSpecifier.h @@ -519,8 +519,8 @@ class NestedNameSpecifierLocBuilder { /// Insertion operator for diagnostics. This allows sending /// NestedNameSpecifiers into a diagnostic with <<. -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, NestedNameSpecifier *NNS) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + NestedNameSpecifier *NNS) { DB.AddTaggedVal(reinterpret_cast(NNS), DiagnosticsEngine::ak_nestednamespec); return DB; diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 5abf60cab4a4a4..51fd8ba51034ed 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -681,8 +681,8 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo { TemplateArgumentListInfo &List) const; }; -const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB, - const TemplateArgument &Arg); +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const TemplateArgument &Arg); inline TemplateSpecializationType::iterator TemplateSpecializationType::end() const { diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index 0f78d7976a4691..9bcf2838dcf135 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -342,8 +342,10 @@ class TemplateName { /// Insertion operator for diagnostics. This allows sending TemplateName's /// into a diagnostic with <<. -const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB, - TemplateName N); +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + TemplateName N); +const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + TemplateName N); /// A structure for storing the information associated with a /// substituted template template parameter. diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 2bf17b6d7ab0e1..d8eece10475a7e 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -7068,28 +7068,55 @@ 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>(AS), + DiagnosticsEngine::ArgumentKind::ak_addrspace); + return DB; +} + /// Insertion operator for partial diagnostics. This allows sending adress /// spaces into a diagnostic with <<. -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &PD, LangAS AS) { +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + LangAS AS) { PD.AddTaggedVal(static_cast>(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 StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &PD, Qualifiers Q) { +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &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(T.getAsOpaquePtr()), + DiagnosticsEngine::ak_qualtype); + return DB; +} + /// Insertion operator for partial diagnostics. This allows sending QualType's /// into a diagnostic with <<. -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &PD, QualType T) { +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + QualType T) { PD.AddTaggedVal(reinterpret_cast(T.getAsOpaquePtr()), DiagnosticsEngine::ak_qualtype); return PD; diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 7ce418bbb99688..304207779c0f18 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -1043,35 +1043,6 @@ class DiagnosticErrorTrap { } }; -/// 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 //===----------------------------------------------------------------------===// @@ -1088,7 +1059,7 @@ class StreamableDiagnosticBase { /// 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 : public StreamableDiagnosticBase { +class DiagnosticBuilder { friend class DiagnosticsEngine; friend class PartialDiagnostic; @@ -1166,27 +1137,12 @@ class DiagnosticBuilder : public StreamableDiagnosticBase { NumArgs = D.NumArgs; } - template 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 ::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. - virtual ~DiagnosticBuilder() { Emit(); } + ~DiagnosticBuilder() { + Emit(); + } /// Forces the diagnostic to be emitted. const DiagnosticBuilder &setForceEmit() const { @@ -1194,7 +1150,16 @@ class DiagnosticBuilder : public StreamableDiagnosticBase { return *this; } - void AddString(StringRef S) const override { + /// 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!"); @@ -1202,8 +1167,7 @@ class DiagnosticBuilder : public StreamableDiagnosticBase { DiagObj->DiagArgumentsStr[NumArgs++] = std::string(S); } - void AddTaggedVal(intptr_t V, - DiagnosticsEngine::ArgumentKind Kind) const override { + 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!"); @@ -1211,12 +1175,12 @@ class DiagnosticBuilder : public StreamableDiagnosticBase { DiagObj->DiagArgumentsVal[NumArgs++] = V; } - void AddSourceRange(const CharSourceRange &R) const override { + 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 override { + void AddFixItHint(const FixItHint &Hint) const { assert(isActive() && "Clients must not add to cleared diagnostic!"); if (!Hint.isNull()) DiagObj->DiagFixItHints.push_back(Hint); @@ -1241,21 +1205,20 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, StringRef S) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + StringRef S) { DB.AddString(S); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const char *Str) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const char *Str) { DB.AddTaggedVal(reinterpret_cast(Str), DiagnosticsEngine::ak_c_string); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, int I) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) { DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; } @@ -1263,27 +1226,26 @@ operator<<(const StreamableDiagnosticBase &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 -inline std::enable_if_t::value, - const StreamableDiagnosticBase &> -operator<<(const StreamableDiagnosticBase &DB, T I) { +inline std::enable_if_t::value, const DiagnosticBuilder &> +operator<<(const DiagnosticBuilder &DB, T I) { DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, unsigned I) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + unsigned I) { DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, tok::TokenKind I) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + tok::TokenKind I) { DB.AddTaggedVal(static_cast(I), DiagnosticsEngine::ak_tokenkind); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const IdentifierInfo *II) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const IdentifierInfo *II) { DB.AddTaggedVal(reinterpret_cast(II), DiagnosticsEngine::ak_identifierinfo); return DB; @@ -1296,64 +1258,63 @@ operator<<(const StreamableDiagnosticBase &DB, const IdentifierInfo *II) { template inline std::enable_if_t< std::is_same, DeclContext>::value, - const StreamableDiagnosticBase &> -operator<<(const StreamableDiagnosticBase &DB, T *DC) { + const DiagnosticBuilder &> +operator<<(const DiagnosticBuilder &DB, T *DC) { DB.AddTaggedVal(reinterpret_cast(DC), DiagnosticsEngine::ak_declcontext); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, SourceRange R) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + SourceRange R) { DB.AddSourceRange(CharSourceRange::getTokenRange(R)); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, ArrayRef Ranges) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + ArrayRef Ranges) { for (SourceRange R : Ranges) DB.AddSourceRange(CharSourceRange::getTokenRange(R)); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const CharSourceRange &R) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const CharSourceRange &R) { DB.AddSourceRange(R); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const FixItHint &Hint) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const FixItHint &Hint) { DB.AddFixItHint(Hint); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, ArrayRef Hints) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + ArrayRef Hints) { for (const FixItHint &Hint : Hints) DB.AddFixItHint(Hint); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, +inline const DiagnosticBuilder & +operator<<(const DiagnosticBuilder &DB, const llvm::Optional &Opt) { if (Opt) DB << *Opt; return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, +inline const DiagnosticBuilder & +operator<<(const DiagnosticBuilder &DB, const llvm::Optional &Opt) { if (Opt) DB << *Opt; return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, - const llvm::Optional &Opt) { +inline const DiagnosticBuilder & +operator<<(const DiagnosticBuilder &DB, const llvm::Optional &Opt) { if (Opt) DB << *Opt; return DB; @@ -1363,8 +1324,8 @@ operator<<(const StreamableDiagnosticBase &DB, /// context-sensitive keyword. using DiagNullabilityKind = std::pair; -const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB, - DiagNullabilityKind nullability); +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + DiagNullabilityKind nullability); inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, unsigned DiagID) { @@ -1376,8 +1337,8 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, return DiagnosticBuilder(this); } -const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB, - llvm::Error &&E); +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + llvm::Error &&E); inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { return Report(SourceLocation(), DiagID); diff --git a/clang/include/clang/Basic/PartialDiagnostic.h b/clang/include/clang/Basic/PartialDiagnostic.h index 5f2fa6efc2791f..107d621f0dec55 100644 --- a/clang/include/clang/Basic/PartialDiagnostic.h +++ b/clang/include/clang/Basic/PartialDiagnostic.h @@ -31,7 +31,7 @@ namespace clang { class DeclContext; class IdentifierInfo; -class PartialDiagnostic : public StreamableDiagnosticBase { +class PartialDiagnostic { public: enum { // The MaxArguments and MaxFixItHints member enum values from @@ -163,15 +163,14 @@ class PartialDiagnostic : public StreamableDiagnosticBase { DiagStorage = nullptr; } -public: - void AddSourceRange(const CharSourceRange &R) const override { + void AddSourceRange(const CharSourceRange &R) const { if (!DiagStorage) DiagStorage = getStorage(); DiagStorage->DiagRanges.push_back(R); } - void AddFixItHint(const FixItHint &Hint) const override { + void AddFixItHint(const FixItHint &Hint) const { if (Hint.isNull()) return; @@ -181,6 +180,7 @@ class PartialDiagnostic : public StreamableDiagnosticBase { DiagStorage->FixItHints.push_back(Hint); } +public: struct NullDiagnostic {}; /// Create a null partial diagnostic, which cannot carry a payload, @@ -198,23 +198,6 @@ class PartialDiagnostic : public StreamableDiagnosticBase { } } - template 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 ::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) { @@ -272,7 +255,9 @@ class PartialDiagnostic : public StreamableDiagnosticBase { return *this; } - virtual ~PartialDiagnostic() { freeStorage(); } + ~PartialDiagnostic() { + freeStorage(); + } void swap(PartialDiagnostic &PD) { std::swap(DiagID, PD.DiagID); @@ -282,8 +267,7 @@ class PartialDiagnostic : public StreamableDiagnosticBase { unsigned getDiagID() const { return DiagID; } - void AddTaggedVal(intptr_t V, - DiagnosticsEngine::ArgumentKind Kind) const override { + void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { if (!DiagStorage) DiagStorage = getStorage(); @@ -293,7 +277,7 @@ class PartialDiagnostic : public StreamableDiagnosticBase { DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V; } - void AddString(StringRef V) const override { + void AddString(StringRef V) const { if (!DiagStorage) DiagStorage = getStorage(); @@ -356,6 +340,70 @@ class PartialDiagnostic : public StreamableDiagnosticBase { == 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(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(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 + friend inline std::enable_if_t::value, + const PartialDiagnostic &> + operator<<(const PartialDiagnostic &PD, T *DC) { + PD.AddTaggedVal(reinterpret_cast(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, diff --git a/clang/include/clang/Sema/Ownership.h b/clang/include/clang/Sema/Ownership.h index 66c4e917c6497e..7c7b1d35c9fd52 100644 --- a/clang/include/clang/Sema/Ownership.h +++ b/clang/include/clang/Sema/Ownership.h @@ -133,7 +133,7 @@ namespace llvm { namespace clang { // Basic - class StreamableDiagnosticBase; + class DiagnosticBuilder; // Determines whether the low bit of the result pointer for the // given UID is always zero. If so, ActionResult will use that bit @@ -280,12 +280,8 @@ namespace clang { inline StmtResult StmtError() { return StmtResult(true); } inline TypeResult TypeError() { return TypeResult(true); } - inline ExprResult ExprError(const StreamableDiagnosticBase &) { - return ExprError(); - } - inline StmtResult StmtError(const StreamableDiagnosticBase &) { - return StmtError(); - } + inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); } + inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); } inline ExprResult ExprEmpty() { return ExprResult(false); } inline StmtResult StmtEmpty() { return StmtResult(false); } diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index 8b4d04afd1a852..8946b12ee03fc2 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -1044,20 +1044,34 @@ enum AttributeDeclKind { ExpectedFunctionWithProtoType, }; -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const ParsedAttr &At) { +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const ParsedAttr &At) { DB.AddTaggedVal(reinterpret_cast(At.getAttrName()), DiagnosticsEngine::ak_identifierinfo); return DB; } -inline const StreamableDiagnosticBase & -operator<<(const StreamableDiagnosticBase &DB, const ParsedAttr *At) { +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const ParsedAttr &At) { + PD.AddTaggedVal(reinterpret_cast(At.getAttrName()), + DiagnosticsEngine::ak_identifierinfo); + return PD; +} + +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const ParsedAttr *At) { DB.AddTaggedVal(reinterpret_cast(At->getAttrName()), DiagnosticsEngine::ak_identifierinfo); return DB; } +inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const ParsedAttr *At) { + PD.AddTaggedVal(reinterpret_cast(At->getAttrName()), + DiagnosticsEngine::ak_identifierinfo); + return PD; +} + } // namespace clang #endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4a22580a22ff45..e05ff2e3a9acc3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1511,17 +1511,6 @@ class Sema final { 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 ::value>::type> - const SemaDiagnosticBuilder &operator<<(T &&V) const { - const StreamableDiagnosticBase &DB = *this; - DB << std::move(V); - return *this; - } }; /// Emit a diagnostic. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 84f747361235a8..fc7abeaae9b17d 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -11298,9 +11298,9 @@ OMPTraitInfo &ASTContext::getNewOMPTraitInfo() { return *OMPTraitInfoVector.back(); } -const StreamableDiagnosticBase &clang:: -operator<<(const StreamableDiagnosticBase &DB, - const ASTContext::SectionInfo &Section) { +const DiagnosticBuilder & +clang::operator<<(const DiagnosticBuilder &DB, + const ASTContext::SectionInfo &Section) { if (Section.Decl) return DB << Section.Decl; return DB << "a prior #pragma section"; diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 9673fbfb5fec1f..59ae5cb300f727 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -3301,7 +3301,12 @@ static const char *getAccessName(AccessSpecifier AS) { llvm_unreachable("Invalid access specifier!"); } -const StreamableDiagnosticBase &clang:: -operator<<(const StreamableDiagnosticBase &DB, AccessSpecifier AS) { +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + AccessSpecifier AS) { + return DB << getAccessName(AS); +} + +const PartialDiagnostic &clang::operator<<(const PartialDiagnostic &DB, + AccessSpecifier AS) { return DB << getAccessName(AS); } diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 0ac84c2357e4b4..6a3d2b30e46eed 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -448,8 +448,8 @@ SourceRange TemplateArgumentLoc::getSourceRange() const { llvm_unreachable("Invalid TemplateArgument Kind!"); } -template -static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) { +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + const TemplateArgument &Arg) { switch (Arg.getKind()) { case TemplateArgument::Null: // This is bad, but not as bad as crashing because of argument @@ -502,11 +502,6 @@ static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) { llvm_unreachable("Invalid TemplateArgument Kind!"); } -const StreamableDiagnosticBase &clang:: -operator<<(const StreamableDiagnosticBase &DB, const TemplateArgument &Arg) { - return DiagTemplateArg(DB, Arg); -} - const ASTTemplateArgumentListInfo * ASTTemplateArgumentListInfo::Create(const ASTContext &C, const TemplateArgumentListInfo &List) { diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 14e3da12db24c2..40a8736ae1afd5 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -254,8 +254,8 @@ TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy, } } -const StreamableDiagnosticBase &clang:: -operator<<(const StreamableDiagnosticBase &DB, TemplateName N) { +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + TemplateName N) { std::string NameStr; llvm::raw_string_ostream OS(NameStr); LangOptions LO; @@ -268,6 +268,20 @@ operator<<(const StreamableDiagnosticBase &DB, TemplateName N) { 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; diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 2673b9d3bea4f1..661eabf9bc7cbb 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -40,9 +40,8 @@ using namespace clang; -const StreamableDiagnosticBase &clang:: -operator<<(const StreamableDiagnosticBase &DB, - DiagNullabilityKind nullability) { +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + DiagNullabilityKind nullability) { StringRef string; switch (nullability.first) { case NullabilityKind::NonNull: @@ -62,8 +61,8 @@ operator<<(const StreamableDiagnosticBase &DB, return DB; } -const StreamableDiagnosticBase &clang:: -operator<<(const StreamableDiagnosticBase &DB, llvm::Error &&E) { +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + llvm::Error &&E) { DB.AddString(toString(std::move(E))); return DB; }