summaryrefslogtreecommitdiffstats
path: root/include/clang/Basic/PartialDiagnostic.h
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-05-07 09:03:25 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-05-07 09:03:25 +0000
commitb8590f3572158bde97f14037c4cc8f4a57c8d810 (patch)
tree6c05c5b75bbe232f21aabf95c569cda5bd493563 /include/clang/Basic/PartialDiagnostic.h
parent4a7376d00df98cbfcad29ee709637707a2f3d46c (diff)
When we suppress an error due to SFINAE, stash the diagnostic away with the
overload candidate, and include its message in any subsequent 'candidate not viable due to substitution failure' note we may produce. To keep the note small (since the 'overload resolution failed' diagnostics are often already very verbose), the text of the SFINAE diagnostic is included as part of the text of the note, and any notes which were attached to it are discarded. There happened to be spare space in OverloadCandidate into which a PartialDiagnosticAt could be squeezed, and this patch goes to lengths to avoid unnecessary PartialDiagnostic copies, resulting in no slowdown that I could measure. (Removal in passing of some PartialDiagnostic copies has resulted in a slightly smaller clang binary overall.) Even on a torture test, I was unable to measure a memory increase of above 0.2%. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156297 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Basic/PartialDiagnostic.h')
-rw-r--r--include/clang/Basic/PartialDiagnostic.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 007e6a4760..7dce172786 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -179,6 +179,12 @@ private:
}
public:
+ struct NullDiagnostic {};
+ /// \brief Create a null partial diagnostic, which cannot carry a payload,
+ /// and only exists to be swapped with a real partial diagnostic.
+ PartialDiagnostic(NullDiagnostic)
+ : DiagID(0), DiagStorage(0), Allocator(0) { }
+
PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
: DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { }
@@ -237,6 +243,12 @@ public:
freeStorage();
}
+ void swap(PartialDiagnostic &PD) {
+ std::swap(DiagID, PD.DiagID);
+ std::swap(DiagStorage, PD.DiagStorage);
+ std::swap(Allocator, PD.Allocator);
+ }
+
unsigned getDiagID() const { return DiagID; }
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
@@ -283,6 +295,18 @@ public:
DB.AddFixItHint(DiagStorage->FixItHints[i]);
}
+ void EmitToString(DiagnosticsEngine &Diags,
+ llvm::SmallVectorImpl<char> &Buf) const {
+ // FIXME: It should be possible to render a diagnostic to a string without
+ // messing with the state of the diagnostics engine.
+ DiagnosticBuilder DB(Diags.Report(getDiagID()));
+ Emit(DB);
+ DB.FlushCounts();
+ Diagnostic(&Diags).FormatDiagnostic(Buf);
+ DB.Clear();
+ Diags.Clear();
+ }
+
/// \brief Clear out this partial diagnostic, giving it a new diagnostic ID
/// and removing all of its arguments, ranges, and fix-it hints.
void Reset(unsigned DiagID = 0) {