PPConditionalDirectiveRecord.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
  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 PPConditionalDirectiveRecord class, which maintains
  10. // a record of conditional directive regions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/Lex/PPConditionalDirectiveRecord.h"
  14. #include "llvm/Support/Capacity.h"
  15. using namespace clang;
  16. PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
  17. : SourceMgr(SM) {
  18. CondDirectiveStack.push_back(SourceLocation());
  19. }
  20. bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
  21. SourceRange Range) const {
  22. if (Range.isInvalid())
  23. return false;
  24. CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
  25. CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
  26. if (low == CondDirectiveLocs.end())
  27. return false;
  28. if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
  29. return false;
  30. CondDirectiveLocsTy::const_iterator
  31. upp = std::upper_bound(low, CondDirectiveLocs.end(),
  32. Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
  33. SourceLocation uppRegion;
  34. if (upp != CondDirectiveLocs.end())
  35. uppRegion = upp->getRegionLoc();
  36. return low->getRegionLoc() != uppRegion;
  37. }
  38. SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
  39. SourceLocation Loc) const {
  40. if (Loc.isInvalid())
  41. return SourceLocation();
  42. if (CondDirectiveLocs.empty())
  43. return SourceLocation();
  44. if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
  45. Loc))
  46. return CondDirectiveStack.back();
  47. CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
  48. CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));
  49. assert(low != CondDirectiveLocs.end());
  50. return low->getRegionLoc();
  51. }
  52. void PPConditionalDirectiveRecord::addCondDirectiveLoc(
  53. CondDirectiveLoc DirLoc) {
  54. // Ignore directives in system headers.
  55. if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
  56. return;
  57. assert(CondDirectiveLocs.empty() ||
  58. SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
  59. DirLoc.getLoc()));
  60. CondDirectiveLocs.push_back(DirLoc);
  61. }
  62. void PPConditionalDirectiveRecord::If(SourceLocation Loc,
  63. SourceRange ConditionRange,
  64. ConditionValueKind ConditionValue) {
  65. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  66. CondDirectiveStack.push_back(Loc);
  67. }
  68. void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
  69. const Token &MacroNameTok,
  70. const MacroDefinition &MD) {
  71. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  72. CondDirectiveStack.push_back(Loc);
  73. }
  74. void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
  75. const Token &MacroNameTok,
  76. const MacroDefinition &MD) {
  77. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  78. CondDirectiveStack.push_back(Loc);
  79. }
  80. void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
  81. SourceRange ConditionRange,
  82. ConditionValueKind ConditionValue,
  83. SourceLocation IfLoc) {
  84. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  85. CondDirectiveStack.back() = Loc;
  86. }
  87. void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, const Token &,
  88. const MacroDefinition &) {
  89. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  90. CondDirectiveStack.back() = Loc;
  91. }
  92. void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,
  93. SourceLocation) {
  94. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  95. CondDirectiveStack.back() = Loc;
  96. }
  97. void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,
  98. const MacroDefinition &) {
  99. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  100. CondDirectiveStack.back() = Loc;
  101. }
  102. void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,
  103. SourceLocation) {
  104. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  105. CondDirectiveStack.back() = Loc;
  106. }
  107. void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
  108. SourceLocation IfLoc) {
  109. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  110. CondDirectiveStack.back() = Loc;
  111. }
  112. void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
  113. SourceLocation IfLoc) {
  114. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  115. assert(!CondDirectiveStack.empty());
  116. CondDirectiveStack.pop_back();
  117. }
  118. size_t PPConditionalDirectiveRecord::getTotalMemory() const {
  119. return llvm::capacity_in_bytes(CondDirectiveLocs);
  120. }