Diagnostic.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. //===- Diagnostic.cpp - C Language Family Diagnostic Handling -------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the Diagnostic-related interfaces.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/Basic/Diagnostic.h"
  13. #include "clang/Basic/CharInfo.h"
  14. #include "clang/Basic/DiagnosticError.h"
  15. #include "clang/Basic/DiagnosticIDs.h"
  16. #include "clang/Basic/DiagnosticOptions.h"
  17. #include "clang/Basic/IdentifierTable.h"
  18. #include "clang/Basic/PartialDiagnostic.h"
  19. #include "clang/Basic/SourceLocation.h"
  20. #include "clang/Basic/SourceManager.h"
  21. #include "clang/Basic/Specifiers.h"
  22. #include "clang/Basic/TokenKinds.h"
  23. #include "llvm/ADT/SmallString.h"
  24. #include "llvm/ADT/SmallVector.h"
  25. #include "llvm/ADT/StringExtras.h"
  26. #include "llvm/ADT/StringRef.h"
  27. #include "llvm/Support/ConvertUTF.h"
  28. #include "llvm/Support/CrashRecoveryContext.h"
  29. #include "llvm/Support/Unicode.h"
  30. #include "llvm/Support/raw_ostream.h"
  31. #include <algorithm>
  32. #include <cassert>
  33. #include <cstddef>
  34. #include <cstdint>
  35. #include <cstring>
  36. #include <limits>
  37. #include <string>
  38. #include <utility>
  39. #include <vector>
  40. using namespace clang;
  41. const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
  42. DiagNullabilityKind nullability) {
  43. StringRef string;
  44. switch (nullability.first) {
  45. case NullabilityKind::NonNull:
  46. string = nullability.second ? "'nonnull'" : "'_Nonnull'";
  47. break;
  48. case NullabilityKind::Nullable:
  49. string = nullability.second ? "'nullable'" : "'_Nullable'";
  50. break;
  51. case NullabilityKind::Unspecified:
  52. string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'";
  53. break;
  54. case NullabilityKind::NullableResult:
  55. assert(!nullability.second &&
  56. "_Nullable_result isn't supported as context-sensitive keyword");
  57. string = "_Nullable_result";
  58. break;
  59. }
  60. DB.AddString(string);
  61. return DB;
  62. }
  63. const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
  64. llvm::Error &&E) {
  65. DB.AddString(toString(std::move(E)));
  66. return DB;
  67. }
  68. static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
  69. StringRef Modifier, StringRef Argument,
  70. ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
  71. SmallVectorImpl<char> &Output,
  72. void *Cookie,
  73. ArrayRef<intptr_t> QualTypeVals) {
  74. StringRef Str = "<can't format argument>";
  75. Output.append(Str.begin(), Str.end());
  76. }
  77. DiagnosticsEngine::DiagnosticsEngine(
  78. IntrusiveRefCntPtr<DiagnosticIDs> diags,
  79. IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, DiagnosticConsumer *client,
  80. bool ShouldOwnClient)
  81. : Diags(std::move(diags)), DiagOpts(std::move(DiagOpts)) {
  82. setClient(client, ShouldOwnClient);
  83. ArgToStringFn = DummyArgToStringFn;
  84. Reset();
  85. }
  86. DiagnosticsEngine::~DiagnosticsEngine() {
  87. // If we own the diagnostic client, destroy it first so that it can access the
  88. // engine from its destructor.
  89. setClient(nullptr);
  90. }
  91. void DiagnosticsEngine::dump() const {
  92. DiagStatesByLoc.dump(*SourceMgr);
  93. }
  94. void DiagnosticsEngine::dump(StringRef DiagName) const {
  95. DiagStatesByLoc.dump(*SourceMgr, DiagName);
  96. }
  97. void DiagnosticsEngine::setClient(DiagnosticConsumer *client,
  98. bool ShouldOwnClient) {
  99. Owner.reset(ShouldOwnClient ? client : nullptr);
  100. Client = client;
  101. }
  102. void DiagnosticsEngine::pushMappings(SourceLocation Loc) {
  103. DiagStateOnPushStack.push_back(GetCurDiagState());
  104. }
  105. bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
  106. if (DiagStateOnPushStack.empty())
  107. return false;
  108. if (DiagStateOnPushStack.back() != GetCurDiagState()) {
  109. // State changed at some point between push/pop.
  110. PushDiagStatePoint(DiagStateOnPushStack.back(), Loc);
  111. }
  112. DiagStateOnPushStack.pop_back();
  113. return true;
  114. }
  115. void DiagnosticsEngine::Reset(bool soft /*=false*/) {
  116. ErrorOccurred = false;
  117. UncompilableErrorOccurred = false;
  118. FatalErrorOccurred = false;
  119. UnrecoverableErrorOccurred = false;
  120. NumWarnings = 0;
  121. NumErrors = 0;
  122. TrapNumErrorsOccurred = 0;
  123. TrapNumUnrecoverableErrorsOccurred = 0;
  124. CurDiagID = std::numeric_limits<unsigned>::max();
  125. LastDiagLevel = DiagnosticIDs::Ignored;
  126. DelayedDiagID = 0;
  127. if (!soft) {
  128. // Clear state related to #pragma diagnostic.
  129. DiagStates.clear();
  130. DiagStatesByLoc.clear();
  131. DiagStateOnPushStack.clear();
  132. // Create a DiagState and DiagStatePoint representing diagnostic changes
  133. // through command-line.
  134. DiagStates.emplace_back();
  135. DiagStatesByLoc.appendFirst(&DiagStates.back());
  136. }
  137. }
  138. void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
  139. StringRef Arg2, StringRef Arg3) {
  140. if (DelayedDiagID)
  141. return;
  142. DelayedDiagID = DiagID;
  143. DelayedDiagArg1 = Arg1.str();
  144. DelayedDiagArg2 = Arg2.str();
  145. DelayedDiagArg3 = Arg3.str();
  146. }
  147. void DiagnosticsEngine::ReportDelayed() {
  148. unsigned ID = DelayedDiagID;
  149. DelayedDiagID = 0;
  150. Report(ID) << DelayedDiagArg1 << DelayedDiagArg2 << DelayedDiagArg3;
  151. }
  152. void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) {
  153. assert(Files.empty() && "not first");
  154. FirstDiagState = CurDiagState = State;
  155. CurDiagStateLoc = SourceLocation();
  156. }
  157. void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr,
  158. SourceLocation Loc,
  159. DiagState *State) {
  160. CurDiagState = State;
  161. CurDiagStateLoc = Loc;
  162. std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
  163. unsigned Offset = Decomp.second;
  164. for (File *F = getFile(SrcMgr, Decomp.first); F;
  165. Offset = F->ParentOffset, F = F->Parent) {
  166. F->HasLocalTransitions = true;
  167. auto &Last = F->StateTransitions.back();
  168. assert(Last.Offset <= Offset && "state transitions added out of order");
  169. if (Last.Offset == Offset) {
  170. if (Last.State == State)
  171. break;
  172. Last.State = State;
  173. continue;
  174. }
  175. F->StateTransitions.push_back({State, Offset});
  176. }
  177. }
  178. DiagnosticsEngine::DiagState *
  179. DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
  180. SourceLocation Loc) const {
  181. // Common case: we have not seen any diagnostic pragmas.
  182. if (Files.empty())
  183. return FirstDiagState;
  184. std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
  185. const File *F = getFile(SrcMgr, Decomp.first);
  186. return F->lookup(Decomp.second);
  187. }
  188. DiagnosticsEngine::DiagState *
  189. DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
  190. auto OnePastIt =
  191. llvm::partition_point(StateTransitions, [=](const DiagStatePoint &P) {
  192. return P.Offset <= Offset;
  193. });
  194. assert(OnePastIt != StateTransitions.begin() && "missing initial state");
  195. return OnePastIt[-1].State;
  196. }
  197. DiagnosticsEngine::DiagStateMap::File *
  198. DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
  199. FileID ID) const {
  200. // Get or insert the File for this ID.
  201. auto Range = Files.equal_range(ID);
  202. if (Range.first != Range.second)
  203. return &Range.first->second;
  204. auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
  205. // We created a new File; look up the diagnostic state at the start of it and
  206. // initialize it.
  207. if (ID.isValid()) {
  208. std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID);
  209. F.Parent = getFile(SrcMgr, Decomp.first);
  210. F.ParentOffset = Decomp.second;
  211. F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0});
  212. } else {
  213. // This is the (imaginary) root file into which we pretend all top-level
  214. // files are included; it descends from the initial state.
  215. //
  216. // FIXME: This doesn't guarantee that we use the same ordering as
  217. // isBeforeInTranslationUnit in the cases where someone invented another
  218. // top-level file and added diagnostic pragmas to it. See the code at the
  219. // end of isBeforeInTranslationUnit for the quirks it deals with.
  220. F.StateTransitions.push_back({FirstDiagState, 0});
  221. }
  222. return &F;
  223. }
  224. void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr,
  225. StringRef DiagName) const {
  226. llvm::errs() << "diagnostic state at ";
  227. CurDiagStateLoc.print(llvm::errs(), SrcMgr);
  228. llvm::errs() << ": " << CurDiagState << "\n";
  229. for (auto &F : Files) {
  230. FileID ID = F.first;
  231. File &File = F.second;
  232. bool PrintedOuterHeading = false;
  233. auto PrintOuterHeading = [&] {
  234. if (PrintedOuterHeading) return;
  235. PrintedOuterHeading = true;
  236. llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue()
  237. << ">: " << SrcMgr.getBufferOrFake(ID).getBufferIdentifier();
  238. if (F.second.Parent) {
  239. std::pair<FileID, unsigned> Decomp =
  240. SrcMgr.getDecomposedIncludedLoc(ID);
  241. assert(File.ParentOffset == Decomp.second);
  242. llvm::errs() << " parent " << File.Parent << " <FileID "
  243. << Decomp.first.getHashValue() << "> ";
  244. SrcMgr.getLocForStartOfFile(Decomp.first)
  245. .getLocWithOffset(Decomp.second)
  246. .print(llvm::errs(), SrcMgr);
  247. }
  248. if (File.HasLocalTransitions)
  249. llvm::errs() << " has_local_transitions";
  250. llvm::errs() << "\n";
  251. };
  252. if (DiagName.empty())
  253. PrintOuterHeading();
  254. for (DiagStatePoint &Transition : File.StateTransitions) {
  255. bool PrintedInnerHeading = false;
  256. auto PrintInnerHeading = [&] {
  257. if (PrintedInnerHeading) return;
  258. PrintedInnerHeading = true;
  259. PrintOuterHeading();
  260. llvm::errs() << " ";
  261. SrcMgr.getLocForStartOfFile(ID)
  262. .getLocWithOffset(Transition.Offset)
  263. .print(llvm::errs(), SrcMgr);
  264. llvm::errs() << ": state " << Transition.State << ":\n";
  265. };
  266. if (DiagName.empty())
  267. PrintInnerHeading();
  268. for (auto &Mapping : *Transition.State) {
  269. StringRef Option =
  270. DiagnosticIDs::getWarningOptionForDiag(Mapping.first);
  271. if (!DiagName.empty() && DiagName != Option)
  272. continue;
  273. PrintInnerHeading();
  274. llvm::errs() << " ";
  275. if (Option.empty())
  276. llvm::errs() << "<unknown " << Mapping.first << ">";
  277. else
  278. llvm::errs() << Option;
  279. llvm::errs() << ": ";
  280. switch (Mapping.second.getSeverity()) {
  281. case diag::Severity::Ignored: llvm::errs() << "ignored"; break;
  282. case diag::Severity::Remark: llvm::errs() << "remark"; break;
  283. case diag::Severity::Warning: llvm::errs() << "warning"; break;
  284. case diag::Severity::Error: llvm::errs() << "error"; break;
  285. case diag::Severity::Fatal: llvm::errs() << "fatal"; break;
  286. }
  287. if (!Mapping.second.isUser())
  288. llvm::errs() << " default";
  289. if (Mapping.second.isPragma())
  290. llvm::errs() << " pragma";
  291. if (Mapping.second.hasNoWarningAsError())
  292. llvm::errs() << " no-error";
  293. if (Mapping.second.hasNoErrorAsFatal())
  294. llvm::errs() << " no-fatal";
  295. if (Mapping.second.wasUpgradedFromWarning())
  296. llvm::errs() << " overruled";
  297. llvm::errs() << "\n";
  298. }
  299. }
  300. }
  301. }
  302. void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
  303. SourceLocation Loc) {
  304. assert(Loc.isValid() && "Adding invalid loc point");
  305. DiagStatesByLoc.append(*SourceMgr, Loc, State);
  306. }
  307. void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
  308. SourceLocation L) {
  309. assert(Diag < diag::DIAG_UPPER_LIMIT &&
  310. "Can only map builtin diagnostics");
  311. assert((Diags->isBuiltinWarningOrExtension(Diag) ||
  312. (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
  313. "Cannot map errors into warnings!");
  314. assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
  315. // Don't allow a mapping to a warning override an error/fatal mapping.
  316. bool WasUpgradedFromWarning = false;
  317. if (Map == diag::Severity::Warning) {
  318. DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
  319. if (Info.getSeverity() == diag::Severity::Error ||
  320. Info.getSeverity() == diag::Severity::Fatal) {
  321. Map = Info.getSeverity();
  322. WasUpgradedFromWarning = true;
  323. }
  324. }
  325. DiagnosticMapping Mapping = makeUserMapping(Map, L);
  326. Mapping.setUpgradedFromWarning(WasUpgradedFromWarning);
  327. // Make sure we propagate the NoWarningAsError flag from an existing
  328. // mapping (which may be the default mapping).
  329. DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
  330. Mapping.setNoWarningAsError(Info.hasNoWarningAsError() ||
  331. Mapping.hasNoWarningAsError());
  332. // Common case; setting all the diagnostics of a group in one place.
  333. if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) &&
  334. DiagStatesByLoc.getCurDiagState()) {
  335. // FIXME: This is theoretically wrong: if the current state is shared with
  336. // some other location (via push/pop) we will change the state for that
  337. // other location as well. This cannot currently happen, as we can't update
  338. // the diagnostic state at the same location at which we pop.
  339. DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping);
  340. return;
  341. }
  342. // A diagnostic pragma occurred, create a new DiagState initialized with
  343. // the current one and a new DiagStatePoint to record at which location
  344. // the new state became active.
  345. DiagStates.push_back(*GetCurDiagState());
  346. DiagStates.back().setMapping(Diag, Mapping);
  347. PushDiagStatePoint(&DiagStates.back(), L);
  348. }
  349. bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
  350. StringRef Group, diag::Severity Map,
  351. SourceLocation Loc) {
  352. // Get the diagnostics in this group.
  353. SmallVector<diag::kind, 256> GroupDiags;
  354. if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags))
  355. return true;
  356. // Set the mapping.
  357. for (diag::kind Diag : GroupDiags)
  358. setSeverity(Diag, Map, Loc);
  359. return false;
  360. }
  361. bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
  362. diag::Group Group,
  363. diag::Severity Map,
  364. SourceLocation Loc) {
  365. return setSeverityForGroup(Flavor, Diags->getWarningOptionForGroup(Group),
  366. Map, Loc);
  367. }
  368. bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
  369. bool Enabled) {
  370. // If we are enabling this feature, just set the diagnostic mappings to map to
  371. // errors.
  372. if (Enabled)
  373. return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
  374. diag::Severity::Error);
  375. // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
  376. // potentially downgrade anything already mapped to be a warning.
  377. // Get the diagnostics in this group.
  378. SmallVector<diag::kind, 8> GroupDiags;
  379. if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
  380. GroupDiags))
  381. return true;
  382. // Perform the mapping change.
  383. for (diag::kind Diag : GroupDiags) {
  384. DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
  385. if (Info.getSeverity() == diag::Severity::Error ||
  386. Info.getSeverity() == diag::Severity::Fatal)
  387. Info.setSeverity(diag::Severity::Warning);
  388. Info.setNoWarningAsError(true);
  389. }
  390. return false;
  391. }
  392. bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
  393. bool Enabled) {
  394. // If we are enabling this feature, just set the diagnostic mappings to map to
  395. // fatal errors.
  396. if (Enabled)
  397. return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
  398. diag::Severity::Fatal);
  399. // Otherwise, we want to set the diagnostic mapping's "no Wfatal-errors" bit,
  400. // and potentially downgrade anything already mapped to be a fatal error.
  401. // Get the diagnostics in this group.
  402. SmallVector<diag::kind, 8> GroupDiags;
  403. if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
  404. GroupDiags))
  405. return true;
  406. // Perform the mapping change.
  407. for (diag::kind Diag : GroupDiags) {
  408. DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
  409. if (Info.getSeverity() == diag::Severity::Fatal)
  410. Info.setSeverity(diag::Severity::Error);
  411. Info.setNoErrorAsFatal(true);
  412. }
  413. return false;
  414. }
  415. void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor,
  416. diag::Severity Map,
  417. SourceLocation Loc) {
  418. // Get all the diagnostics.
  419. std::vector<diag::kind> AllDiags;
  420. DiagnosticIDs::getAllDiagnostics(Flavor, AllDiags);
  421. // Set the mapping.
  422. for (diag::kind Diag : AllDiags)
  423. if (Diags->isBuiltinWarningOrExtension(Diag))
  424. setSeverity(Diag, Map, Loc);
  425. }
  426. void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
  427. assert(CurDiagID == std::numeric_limits<unsigned>::max() &&
  428. "Multiple diagnostics in flight at once!");
  429. CurDiagLoc = storedDiag.getLocation();
  430. CurDiagID = storedDiag.getID();
  431. DiagStorage.NumDiagArgs = 0;
  432. DiagStorage.DiagRanges.clear();
  433. DiagStorage.DiagRanges.append(storedDiag.range_begin(),
  434. storedDiag.range_end());
  435. DiagStorage.FixItHints.clear();
  436. DiagStorage.FixItHints.append(storedDiag.fixit_begin(),
  437. storedDiag.fixit_end());
  438. assert(Client && "DiagnosticConsumer not set!");
  439. Level DiagLevel = storedDiag.getLevel();
  440. Diagnostic Info(this, storedDiag.getMessage());
  441. Client->HandleDiagnostic(DiagLevel, Info);
  442. if (Client->IncludeInDiagnosticCounts()) {
  443. if (DiagLevel == DiagnosticsEngine::Warning)
  444. ++NumWarnings;
  445. }
  446. CurDiagID = std::numeric_limits<unsigned>::max();
  447. }
  448. bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) {
  449. assert(getClient() && "DiagnosticClient not set!");
  450. bool Emitted;
  451. if (Force) {
  452. Diagnostic Info(this);
  453. // Figure out the diagnostic level of this message.
  454. DiagnosticIDs::Level DiagLevel
  455. = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this);
  456. Emitted = (DiagLevel != DiagnosticIDs::Ignored);
  457. if (Emitted) {
  458. // Emit the diagnostic regardless of suppression level.
  459. Diags->EmitDiag(*this, DiagLevel);
  460. }
  461. } else {
  462. // Process the diagnostic, sending the accumulated information to the
  463. // DiagnosticConsumer.
  464. Emitted = ProcessDiag();
  465. }
  466. // Clear out the current diagnostic object.
  467. Clear();
  468. // If there was a delayed diagnostic, emit it now.
  469. if (!Force && DelayedDiagID)
  470. ReportDelayed();
  471. return Emitted;
  472. }
  473. DiagnosticConsumer::~DiagnosticConsumer() = default;
  474. void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
  475. const Diagnostic &Info) {
  476. if (!IncludeInDiagnosticCounts())
  477. return;
  478. if (DiagLevel == DiagnosticsEngine::Warning)
  479. ++NumWarnings;
  480. else if (DiagLevel >= DiagnosticsEngine::Error)
  481. ++NumErrors;
  482. }
  483. /// ModifierIs - Return true if the specified modifier matches specified string.
  484. template <std::size_t StrLen>
  485. static bool ModifierIs(const char *Modifier, unsigned ModifierLen,
  486. const char (&Str)[StrLen]) {
  487. return StrLen-1 == ModifierLen && memcmp(Modifier, Str, StrLen-1) == 0;
  488. }
  489. /// ScanForward - Scans forward, looking for the given character, skipping
  490. /// nested clauses and escaped characters.
  491. static const char *ScanFormat(const char *I, const char *E, char Target) {
  492. unsigned Depth = 0;
  493. for ( ; I != E; ++I) {
  494. if (Depth == 0 && *I == Target) return I;
  495. if (Depth != 0 && *I == '}') Depth--;
  496. if (*I == '%') {
  497. I++;
  498. if (I == E) break;
  499. // Escaped characters get implicitly skipped here.
  500. // Format specifier.
  501. if (!isDigit(*I) && !isPunctuation(*I)) {
  502. for (I++; I != E && !isDigit(*I) && *I != '{'; I++) ;
  503. if (I == E) break;
  504. if (*I == '{')
  505. Depth++;
  506. }
  507. }
  508. }
  509. return E;
  510. }
  511. /// HandleSelectModifier - Handle the integer 'select' modifier. This is used
  512. /// like this: %select{foo|bar|baz}2. This means that the integer argument
  513. /// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'.
  514. /// If the value is 1, it prints 'bar'. If it has the value 2, it prints 'baz'.
  515. /// This is very useful for certain classes of variant diagnostics.
  516. static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo,
  517. const char *Argument, unsigned ArgumentLen,
  518. SmallVectorImpl<char> &OutStr) {
  519. const char *ArgumentEnd = Argument+ArgumentLen;
  520. // Skip over 'ValNo' |'s.
  521. while (ValNo) {
  522. const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|');
  523. assert(NextVal != ArgumentEnd && "Value for integer select modifier was"
  524. " larger than the number of options in the diagnostic string!");
  525. Argument = NextVal+1; // Skip this string.
  526. --ValNo;
  527. }
  528. // Get the end of the value. This is either the } or the |.
  529. const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|');
  530. // Recursively format the result of the select clause into the output string.
  531. DInfo.FormatDiagnostic(Argument, EndPtr, OutStr);
  532. }
  533. /// HandleIntegerSModifier - Handle the integer 's' modifier. This adds the
  534. /// letter 's' to the string if the value is not 1. This is used in cases like
  535. /// this: "you idiot, you have %4 parameter%s4!".
  536. static void HandleIntegerSModifier(unsigned ValNo,
  537. SmallVectorImpl<char> &OutStr) {
  538. if (ValNo != 1)
  539. OutStr.push_back('s');
  540. }
  541. /// HandleOrdinalModifier - Handle the integer 'ord' modifier. This
  542. /// prints the ordinal form of the given integer, with 1 corresponding
  543. /// to the first ordinal. Currently this is hard-coded to use the
  544. /// English form.
  545. static void HandleOrdinalModifier(unsigned ValNo,
  546. SmallVectorImpl<char> &OutStr) {
  547. assert(ValNo != 0 && "ValNo must be strictly positive!");
  548. llvm::raw_svector_ostream Out(OutStr);
  549. // We could use text forms for the first N ordinals, but the numeric
  550. // forms are actually nicer in diagnostics because they stand out.
  551. Out << ValNo << llvm::getOrdinalSuffix(ValNo);
  552. }
  553. /// PluralNumber - Parse an unsigned integer and advance Start.
  554. static unsigned PluralNumber(const char *&Start, const char *End) {
  555. // Programming 101: Parse a decimal number :-)
  556. unsigned Val = 0;
  557. while (Start != End && *Start >= '0' && *Start <= '9') {
  558. Val *= 10;
  559. Val += *Start - '0';
  560. ++Start;
  561. }
  562. return Val;
  563. }
  564. /// TestPluralRange - Test if Val is in the parsed range. Modifies Start.
  565. static bool TestPluralRange(unsigned Val, const char *&Start, const char *End) {
  566. if (*Start != '[') {
  567. unsigned Ref = PluralNumber(Start, End);
  568. return Ref == Val;
  569. }
  570. ++Start;
  571. unsigned Low = PluralNumber(Start, End);
  572. assert(*Start == ',' && "Bad plural expression syntax: expected ,");
  573. ++Start;
  574. unsigned High = PluralNumber(Start, End);
  575. assert(*Start == ']' && "Bad plural expression syntax: expected )");
  576. ++Start;
  577. return Low <= Val && Val <= High;
  578. }
  579. /// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier.
  580. static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
  581. // Empty condition?
  582. if (*Start == ':')
  583. return true;
  584. while (true) {
  585. char C = *Start;
  586. if (C == '%') {
  587. // Modulo expression
  588. ++Start;
  589. unsigned Arg = PluralNumber(Start, End);
  590. assert(*Start == '=' && "Bad plural expression syntax: expected =");
  591. ++Start;
  592. unsigned ValMod = ValNo % Arg;
  593. if (TestPluralRange(ValMod, Start, End))
  594. return true;
  595. } else {
  596. assert((C == '[' || (C >= '0' && C <= '9')) &&
  597. "Bad plural expression syntax: unexpected character");
  598. // Range expression
  599. if (TestPluralRange(ValNo, Start, End))
  600. return true;
  601. }
  602. // Scan for next or-expr part.
  603. Start = std::find(Start, End, ',');
  604. if (Start == End)
  605. break;
  606. ++Start;
  607. }
  608. return false;
  609. }
  610. /// HandlePluralModifier - Handle the integer 'plural' modifier. This is used
  611. /// for complex plural forms, or in languages where all plurals are complex.
  612. /// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are
  613. /// conditions that are tested in order, the form corresponding to the first
  614. /// that applies being emitted. The empty condition is always true, making the
  615. /// last form a default case.
  616. /// Conditions are simple boolean expressions, where n is the number argument.
  617. /// Here are the rules.
  618. /// condition := expression | empty
  619. /// empty := -> always true
  620. /// expression := numeric [',' expression] -> logical or
  621. /// numeric := range -> true if n in range
  622. /// | '%' number '=' range -> true if n % number in range
  623. /// range := number
  624. /// | '[' number ',' number ']' -> ranges are inclusive both ends
  625. ///
  626. /// Here are some examples from the GNU gettext manual written in this form:
  627. /// English:
  628. /// {1:form0|:form1}
  629. /// Latvian:
  630. /// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0}
  631. /// Gaeilge:
  632. /// {1:form0|2:form1|:form2}
  633. /// Romanian:
  634. /// {1:form0|0,%100=[1,19]:form1|:form2}
  635. /// Lithuanian:
  636. /// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1}
  637. /// Russian (requires repeated form):
  638. /// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2}
  639. /// Slovak
  640. /// {1:form0|[2,4]:form1|:form2}
  641. /// Polish (requires repeated form):
  642. /// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
  643. static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo,
  644. const char *Argument, unsigned ArgumentLen,
  645. SmallVectorImpl<char> &OutStr) {
  646. const char *ArgumentEnd = Argument + ArgumentLen;
  647. while (true) {
  648. assert(Argument < ArgumentEnd && "Plural expression didn't match.");
  649. const char *ExprEnd = Argument;
  650. while (*ExprEnd != ':') {
  651. assert(ExprEnd != ArgumentEnd && "Plural missing expression end");
  652. ++ExprEnd;
  653. }
  654. if (EvalPluralExpr(ValNo, Argument, ExprEnd)) {
  655. Argument = ExprEnd + 1;
  656. ExprEnd = ScanFormat(Argument, ArgumentEnd, '|');
  657. // Recursively format the result of the plural clause into the
  658. // output string.
  659. DInfo.FormatDiagnostic(Argument, ExprEnd, OutStr);
  660. return;
  661. }
  662. Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1;
  663. }
  664. }
  665. /// Returns the friendly description for a token kind that will appear
  666. /// without quotes in diagnostic messages. These strings may be translatable in
  667. /// future.
  668. static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) {
  669. switch (Kind) {
  670. case tok::identifier:
  671. return "identifier";
  672. default:
  673. return nullptr;
  674. }
  675. }
  676. /// FormatDiagnostic - Format this diagnostic into a string, substituting the
  677. /// formal arguments into the %0 slots. The result is appended onto the Str
  678. /// array.
  679. void Diagnostic::
  680. FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
  681. if (!StoredDiagMessage.empty()) {
  682. OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end());
  683. return;
  684. }
  685. StringRef Diag =
  686. getDiags()->getDiagnosticIDs()->getDescription(getID());
  687. FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
  688. }
  689. /// pushEscapedString - Append Str to the diagnostic buffer,
  690. /// escaping non-printable characters and ill-formed code unit sequences.
  691. static void pushEscapedString(StringRef Str, SmallVectorImpl<char> &OutStr) {
  692. OutStr.reserve(OutStr.size() + Str.size());
  693. auto *Begin = reinterpret_cast<const unsigned char *>(Str.data());
  694. llvm::raw_svector_ostream OutStream(OutStr);
  695. const unsigned char *End = Begin + Str.size();
  696. while (Begin != End) {
  697. // ASCII case
  698. if (isPrintable(*Begin) || isWhitespace(*Begin)) {
  699. OutStream << *Begin;
  700. ++Begin;
  701. continue;
  702. }
  703. if (llvm::isLegalUTF8Sequence(Begin, End)) {
  704. llvm::UTF32 CodepointValue;
  705. llvm::UTF32 *CpPtr = &CodepointValue;
  706. const unsigned char *CodepointBegin = Begin;
  707. const unsigned char *CodepointEnd =
  708. Begin + llvm::getNumBytesForUTF8(*Begin);
  709. llvm::ConversionResult Res = llvm::ConvertUTF8toUTF32(
  710. &Begin, CodepointEnd, &CpPtr, CpPtr + 1, llvm::strictConversion);
  711. (void)Res;
  712. assert(
  713. llvm::conversionOK == Res &&
  714. "the sequence is legal UTF-8 but we couldn't convert it to UTF-32");
  715. assert(Begin == CodepointEnd &&
  716. "we must be further along in the string now");
  717. if (llvm::sys::unicode::isPrintable(CodepointValue) ||
  718. llvm::sys::unicode::isFormatting(CodepointValue)) {
  719. OutStr.append(CodepointBegin, CodepointEnd);
  720. continue;
  721. }
  722. // Unprintable code point.
  723. OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true)
  724. << ">";
  725. continue;
  726. }
  727. // Invalid code unit.
  728. OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">";
  729. ++Begin;
  730. }
  731. }
  732. void Diagnostic::
  733. FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
  734. SmallVectorImpl<char> &OutStr) const {
  735. // When the diagnostic string is only "%0", the entire string is being given
  736. // by an outside source. Remove unprintable characters from this string
  737. // and skip all the other string processing.
  738. if (DiagEnd - DiagStr == 2 &&
  739. StringRef(DiagStr, DiagEnd - DiagStr).equals("%0") &&
  740. getArgKind(0) == DiagnosticsEngine::ak_std_string) {
  741. const std::string &S = getArgStdStr(0);
  742. pushEscapedString(S, OutStr);
  743. return;
  744. }
  745. /// FormattedArgs - Keep track of all of the arguments formatted by
  746. /// ConvertArgToString and pass them into subsequent calls to
  747. /// ConvertArgToString, allowing the implementation to avoid redundancies in
  748. /// obvious cases.
  749. SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs;
  750. /// QualTypeVals - Pass a vector of arrays so that QualType names can be
  751. /// compared to see if more information is needed to be printed.
  752. SmallVector<intptr_t, 2> QualTypeVals;
  753. SmallString<64> Tree;
  754. for (unsigned i = 0, e = getNumArgs(); i < e; ++i)
  755. if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
  756. QualTypeVals.push_back(getRawArg(i));
  757. while (DiagStr != DiagEnd) {
  758. if (DiagStr[0] != '%') {
  759. // Append non-%0 substrings to Str if we have one.
  760. const char *StrEnd = std::find(DiagStr, DiagEnd, '%');
  761. OutStr.append(DiagStr, StrEnd);
  762. DiagStr = StrEnd;
  763. continue;
  764. } else if (isPunctuation(DiagStr[1])) {
  765. OutStr.push_back(DiagStr[1]); // %% -> %.
  766. DiagStr += 2;
  767. continue;
  768. }
  769. // Skip the %.
  770. ++DiagStr;
  771. // This must be a placeholder for a diagnostic argument. The format for a
  772. // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0".
  773. // The digit is a number from 0-9 indicating which argument this comes from.
  774. // The modifier is a string of digits from the set [-a-z]+, arguments is a
  775. // brace enclosed string.
  776. const char *Modifier = nullptr, *Argument = nullptr;
  777. unsigned ModifierLen = 0, ArgumentLen = 0;
  778. // Check to see if we have a modifier. If so eat it.
  779. if (!isDigit(DiagStr[0])) {
  780. Modifier = DiagStr;
  781. while (DiagStr[0] == '-' ||
  782. (DiagStr[0] >= 'a' && DiagStr[0] <= 'z'))
  783. ++DiagStr;
  784. ModifierLen = DiagStr-Modifier;
  785. // If we have an argument, get it next.
  786. if (DiagStr[0] == '{') {
  787. ++DiagStr; // Skip {.
  788. Argument = DiagStr;
  789. DiagStr = ScanFormat(DiagStr, DiagEnd, '}');
  790. assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!");
  791. ArgumentLen = DiagStr-Argument;
  792. ++DiagStr; // Skip }.
  793. }
  794. }
  795. assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic");
  796. unsigned ArgNo = *DiagStr++ - '0';
  797. // Only used for type diffing.
  798. unsigned ArgNo2 = ArgNo;
  799. DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo);
  800. if (ModifierIs(Modifier, ModifierLen, "diff")) {
  801. assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) &&
  802. "Invalid format for diff modifier");
  803. ++DiagStr; // Comma.
  804. ArgNo2 = *DiagStr++ - '0';
  805. DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2);
  806. if (Kind == DiagnosticsEngine::ak_qualtype &&
  807. Kind2 == DiagnosticsEngine::ak_qualtype)
  808. Kind = DiagnosticsEngine::ak_qualtype_pair;
  809. else {
  810. // %diff only supports QualTypes. For other kinds of arguments,
  811. // use the default printing. For example, if the modifier is:
  812. // "%diff{compare $ to $|other text}1,2"
  813. // treat it as:
  814. // "compare %1 to %2"
  815. const char *ArgumentEnd = Argument + ArgumentLen;
  816. const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
  817. assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd &&
  818. "Found too many '|'s in a %diff modifier!");
  819. const char *FirstDollar = ScanFormat(Argument, Pipe, '$');
  820. const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$');
  821. const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) };
  822. const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) };
  823. FormatDiagnostic(Argument, FirstDollar, OutStr);
  824. FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr);
  825. FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
  826. FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr);
  827. FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
  828. continue;
  829. }
  830. }
  831. switch (Kind) {
  832. // ---- STRINGS ----
  833. case DiagnosticsEngine::ak_std_string: {
  834. const std::string &S = getArgStdStr(ArgNo);
  835. assert(ModifierLen == 0 && "No modifiers for strings yet");
  836. pushEscapedString(S, OutStr);
  837. break;
  838. }
  839. case DiagnosticsEngine::ak_c_string: {
  840. const char *S = getArgCStr(ArgNo);
  841. assert(ModifierLen == 0 && "No modifiers for strings yet");
  842. // Don't crash if get passed a null pointer by accident.
  843. if (!S)
  844. S = "(null)";
  845. pushEscapedString(S, OutStr);
  846. break;
  847. }
  848. // ---- INTEGERS ----
  849. case DiagnosticsEngine::ak_sint: {
  850. int64_t Val = getArgSInt(ArgNo);
  851. if (ModifierIs(Modifier, ModifierLen, "select")) {
  852. HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen,
  853. OutStr);
  854. } else if (ModifierIs(Modifier, ModifierLen, "s")) {
  855. HandleIntegerSModifier(Val, OutStr);
  856. } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
  857. HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
  858. OutStr);
  859. } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
  860. HandleOrdinalModifier((unsigned)Val, OutStr);
  861. } else {
  862. assert(ModifierLen == 0 && "Unknown integer modifier");
  863. llvm::raw_svector_ostream(OutStr) << Val;
  864. }
  865. break;
  866. }
  867. case DiagnosticsEngine::ak_uint: {
  868. uint64_t Val = getArgUInt(ArgNo);
  869. if (ModifierIs(Modifier, ModifierLen, "select")) {
  870. HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr);
  871. } else if (ModifierIs(Modifier, ModifierLen, "s")) {
  872. HandleIntegerSModifier(Val, OutStr);
  873. } else if (ModifierIs(Modifier, ModifierLen, "plural")) {
  874. HandlePluralModifier(*this, (unsigned)Val, Argument, ArgumentLen,
  875. OutStr);
  876. } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
  877. HandleOrdinalModifier(Val, OutStr);
  878. } else {
  879. assert(ModifierLen == 0 && "Unknown integer modifier");
  880. llvm::raw_svector_ostream(OutStr) << Val;
  881. }
  882. break;
  883. }
  884. // ---- TOKEN SPELLINGS ----
  885. case DiagnosticsEngine::ak_tokenkind: {
  886. tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo));
  887. assert(ModifierLen == 0 && "No modifiers for token kinds yet");
  888. llvm::raw_svector_ostream Out(OutStr);
  889. if (const char *S = tok::getPunctuatorSpelling(Kind))
  890. // Quoted token spelling for punctuators.
  891. Out << '\'' << S << '\'';
  892. else if ((S = tok::getKeywordSpelling(Kind)))
  893. // Unquoted token spelling for keywords.
  894. Out << S;
  895. else if ((S = getTokenDescForDiagnostic(Kind)))
  896. // Unquoted translatable token name.
  897. Out << S;
  898. else if ((S = tok::getTokenName(Kind)))
  899. // Debug name, shouldn't appear in user-facing diagnostics.
  900. Out << '<' << S << '>';
  901. else
  902. Out << "(null)";
  903. break;
  904. }
  905. // ---- NAMES and TYPES ----
  906. case DiagnosticsEngine::ak_identifierinfo: {
  907. const IdentifierInfo *II = getArgIdentifier(ArgNo);
  908. assert(ModifierLen == 0 && "No modifiers for strings yet");
  909. // Don't crash if get passed a null pointer by accident.
  910. if (!II) {
  911. const char *S = "(null)";
  912. OutStr.append(S, S + strlen(S));
  913. continue;
  914. }
  915. llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
  916. break;
  917. }
  918. case DiagnosticsEngine::ak_addrspace:
  919. case DiagnosticsEngine::ak_qual:
  920. case DiagnosticsEngine::ak_qualtype:
  921. case DiagnosticsEngine::ak_declarationname:
  922. case DiagnosticsEngine::ak_nameddecl:
  923. case DiagnosticsEngine::ak_nestednamespec:
  924. case DiagnosticsEngine::ak_declcontext:
  925. case DiagnosticsEngine::ak_attr:
  926. getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
  927. StringRef(Modifier, ModifierLen),
  928. StringRef(Argument, ArgumentLen),
  929. FormattedArgs,
  930. OutStr, QualTypeVals);
  931. break;
  932. case DiagnosticsEngine::ak_qualtype_pair: {
  933. // Create a struct with all the info needed for printing.
  934. TemplateDiffTypes TDT;
  935. TDT.FromType = getRawArg(ArgNo);
  936. TDT.ToType = getRawArg(ArgNo2);
  937. TDT.ElideType = getDiags()->ElideType;
  938. TDT.ShowColors = getDiags()->ShowColors;
  939. TDT.TemplateDiffUsed = false;
  940. intptr_t val = reinterpret_cast<intptr_t>(&TDT);
  941. const char *ArgumentEnd = Argument + ArgumentLen;
  942. const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|');
  943. // Print the tree. If this diagnostic already has a tree, skip the
  944. // second tree.
  945. if (getDiags()->PrintTemplateTree && Tree.empty()) {
  946. TDT.PrintFromType = true;
  947. TDT.PrintTree = true;
  948. getDiags()->ConvertArgToString(Kind, val,
  949. StringRef(Modifier, ModifierLen),
  950. StringRef(Argument, ArgumentLen),
  951. FormattedArgs,
  952. Tree, QualTypeVals);
  953. // If there is no tree information, fall back to regular printing.
  954. if (!Tree.empty()) {
  955. FormatDiagnostic(Pipe + 1, ArgumentEnd, OutStr);
  956. break;
  957. }
  958. }
  959. // Non-tree printing, also the fall-back when tree printing fails.
  960. // The fall-back is triggered when the types compared are not templates.
  961. const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$');
  962. const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$');
  963. // Append before text
  964. FormatDiagnostic(Argument, FirstDollar, OutStr);
  965. // Append first type
  966. TDT.PrintTree = false;
  967. TDT.PrintFromType = true;
  968. getDiags()->ConvertArgToString(Kind, val,
  969. StringRef(Modifier, ModifierLen),
  970. StringRef(Argument, ArgumentLen),
  971. FormattedArgs,
  972. OutStr, QualTypeVals);
  973. if (!TDT.TemplateDiffUsed)
  974. FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
  975. TDT.FromType));
  976. // Append middle text
  977. FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
  978. // Append second type
  979. TDT.PrintFromType = false;
  980. getDiags()->ConvertArgToString(Kind, val,
  981. StringRef(Modifier, ModifierLen),
  982. StringRef(Argument, ArgumentLen),
  983. FormattedArgs,
  984. OutStr, QualTypeVals);
  985. if (!TDT.TemplateDiffUsed)
  986. FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
  987. TDT.ToType));
  988. // Append end text
  989. FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
  990. break;
  991. }
  992. }
  993. // Remember this argument info for subsequent formatting operations. Turn
  994. // std::strings into a null terminated string to make it be the same case as
  995. // all the other ones.
  996. if (Kind == DiagnosticsEngine::ak_qualtype_pair)
  997. continue;
  998. else if (Kind != DiagnosticsEngine::ak_std_string)
  999. FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
  1000. else
  1001. FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string,
  1002. (intptr_t)getArgStdStr(ArgNo).c_str()));
  1003. }
  1004. // Append the type tree to the end of the diagnostics.
  1005. OutStr.append(Tree.begin(), Tree.end());
  1006. }
  1007. StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
  1008. StringRef Message)
  1009. : ID(ID), Level(Level), Message(Message) {}
  1010. StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level,
  1011. const Diagnostic &Info)
  1012. : ID(Info.getID()), Level(Level) {
  1013. assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
  1014. "Valid source location without setting a source manager for diagnostic");
  1015. if (Info.getLocation().isValid())
  1016. Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
  1017. SmallString<64> Message;
  1018. Info.FormatDiagnostic(Message);
  1019. this->Message.assign(Message.begin(), Message.end());
  1020. this->Ranges.assign(Info.getRanges().begin(), Info.getRanges().end());
  1021. this->FixIts.assign(Info.getFixItHints().begin(), Info.getFixItHints().end());
  1022. }
  1023. StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
  1024. StringRef Message, FullSourceLoc Loc,
  1025. ArrayRef<CharSourceRange> Ranges,
  1026. ArrayRef<FixItHint> FixIts)
  1027. : ID(ID), Level(Level), Loc(Loc), Message(Message),
  1028. Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end())
  1029. {
  1030. }
  1031. llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
  1032. const StoredDiagnostic &SD) {
  1033. if (SD.getLocation().hasManager())
  1034. OS << SD.getLocation().printToString(SD.getLocation().getManager()) << ": ";
  1035. OS << SD.getMessage();
  1036. return OS;
  1037. }
  1038. /// IncludeInDiagnosticCounts - This method (whose default implementation
  1039. /// returns true) indicates whether the diagnostics handled by this
  1040. /// DiagnosticConsumer should be included in the number of diagnostics
  1041. /// reported by DiagnosticsEngine.
  1042. bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
  1043. void IgnoringDiagConsumer::anchor() {}
  1044. ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() = default;
  1045. void ForwardingDiagnosticConsumer::HandleDiagnostic(
  1046. DiagnosticsEngine::Level DiagLevel,
  1047. const Diagnostic &Info) {
  1048. Target.HandleDiagnostic(DiagLevel, Info);
  1049. }
  1050. void ForwardingDiagnosticConsumer::clear() {
  1051. DiagnosticConsumer::clear();
  1052. Target.clear();
  1053. }
  1054. bool ForwardingDiagnosticConsumer::IncludeInDiagnosticCounts() const {
  1055. return Target.IncludeInDiagnosticCounts();
  1056. }
  1057. PartialDiagnostic::DiagStorageAllocator::DiagStorageAllocator() {
  1058. for (unsigned I = 0; I != NumCached; ++I)
  1059. FreeList[I] = Cached + I;
  1060. NumFreeListEntries = NumCached;
  1061. }
  1062. PartialDiagnostic::DiagStorageAllocator::~DiagStorageAllocator() {
  1063. // Don't assert if we are in a CrashRecovery context, as this invariant may
  1064. // be invalidated during a crash.
  1065. assert((NumFreeListEntries == NumCached ||
  1066. llvm::CrashRecoveryContext::isRecoveringFromCrash()) &&
  1067. "A partial is on the lam");
  1068. }
  1069. char DiagnosticError::ID;