@@ -99,7 +99,7 @@ void FileSpecificDiagnosticConsumer::computeConsumersOrderedByRange(
9999 " overlapping ranges despite having distinct files" );
100100}
101101
102- DiagnosticConsumer *
102+ Optional< DiagnosticConsumer *>
103103FileSpecificDiagnosticConsumer::consumerForLocation (SourceManager &SM,
104104 SourceLoc loc) const {
105105 // If there's only one consumer, we'll use it no matter what, because...
@@ -111,7 +111,7 @@ FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
111111
112112 // Diagnostics with invalid locations always go to every consumer.
113113 if (loc.isInvalid ())
114- return nullptr ;
114+ return None ;
115115
116116 // This map is generated on first use and cached, to allow the
117117 // FileSpecificDiagnosticConsumer to be set up before the source files are
@@ -121,15 +121,15 @@ FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
121121 // It's possible to get here while a bridging header PCH is being
122122 // attached-to, if there's some sort of AST-reader warning or error, which
123123 // happens before CompilerInstance::setUpInputs(), at which point _no_
124- // source buffers are loaded in yet. In that case we return nullptr , rather
124+ // source buffers are loaded in yet. In that case we return None , rather
125125 // than trying to build a nonsensical map (and actually crashing since we
126126 // can't find buffers for the inputs).
127127 assert (!SubConsumers.empty ());
128128 if (!SM.getIDForBufferIdentifier (SubConsumers.begin ()->first ).hasValue ()) {
129129 assert (llvm::none_of (SubConsumers, [&](const ConsumerPair &pair) {
130130 return SM.getIDForBufferIdentifier (pair.first ).hasValue ();
131131 }));
132- return nullptr ;
132+ return None ;
133133 }
134134 auto *mutableThis = const_cast <FileSpecificDiagnosticConsumer*>(this );
135135 mutableThis->computeConsumersOrderedByRange (SM);
@@ -155,15 +155,15 @@ FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
155155 return possiblyContainingRangeIter->second ;
156156 }
157157
158- return nullptr ;
158+ return None ;
159159}
160160
161161void FileSpecificDiagnosticConsumer::handleDiagnostic (
162162 SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind,
163163 StringRef FormatString, ArrayRef<DiagnosticArgument> FormatArgs,
164164 const DiagnosticInfo &Info) {
165165
166- DiagnosticConsumer *specificConsumer;
166+ Optional< DiagnosticConsumer *> specificConsumer;
167167 switch (Kind) {
168168 case DiagnosticKind::Error:
169169 case DiagnosticKind::Warning:
@@ -176,23 +176,25 @@ void FileSpecificDiagnosticConsumer::handleDiagnostic(
176176 break ;
177177 }
178178
179- if (specificConsumer) {
180- specificConsumer->handleDiagnostic (SM, Loc, Kind, FormatString, FormatArgs,
181- Info);
182- } else {
179+ if (!specificConsumer.hasValue ()) {
183180 for (auto &subConsumer : SubConsumers) {
184- subConsumer.second ->handleDiagnostic (SM, Loc, Kind, FormatString,
185- FormatArgs, Info);
181+ if (subConsumer.second ) {
182+ subConsumer.second ->handleDiagnostic (SM, Loc, Kind, FormatString,
183+ FormatArgs, Info);
184+ }
186185 }
187- }
186+ } else if (DiagnosticConsumer *c = specificConsumer.getValue ())
187+ c->handleDiagnostic (SM, Loc, Kind, FormatString, FormatArgs, Info);
188+ else
189+ ; // Suppress non-primary diagnostic in batch mode.
188190}
189191
190192bool FileSpecificDiagnosticConsumer::finishProcessing () {
191193 // Deliberately don't use std::any_of here because we don't want early-exit
192194 // behavior.
193195 bool hadError = false ;
194196 for (auto &subConsumer : SubConsumers)
195- hadError |= subConsumer.second ->finishProcessing ();
197+ hadError |= subConsumer.second && subConsumer. second ->finishProcessing ();
196198 return hadError;
197199}
198200
0 commit comments