PPConditionalDirectiveRecord.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the PPConditionalDirectiveRecord class, which maintains
  11. // a record of conditional directive regions.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/Lex/PPConditionalDirectiveRecord.h"
  15. #include "llvm/Support/Capacity.h"
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. using namespace clang;
  19. PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
  20. : SourceMgr(SM) {
  21. CondDirectiveStack.push_back(SourceLocation());
  22. }
  23. bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
  24. SourceRange Range) const {
  25. if (Range.isInvalid())
  26. return false;
  27. CondDirectiveLocsTy::const_iterator
  28. low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
  29. Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
  30. if (low == CondDirectiveLocs.end())
  31. return false;
  32. if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
  33. return false;
  34. CondDirectiveLocsTy::const_iterator
  35. upp = std::upper_bound(low, CondDirectiveLocs.end(),
  36. Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
  37. SourceLocation uppRegion;
  38. if (upp != CondDirectiveLocs.end())
  39. uppRegion = upp->getRegionLoc();
  40. return low->getRegionLoc() != uppRegion;
  41. }
  42. SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
  43. SourceLocation Loc) const {
  44. if (Loc.isInvalid())
  45. return SourceLocation();
  46. if (CondDirectiveLocs.empty())
  47. return SourceLocation();
  48. if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
  49. Loc))
  50. return CondDirectiveStack.back();
  51. CondDirectiveLocsTy::const_iterator
  52. low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
  53. Loc, CondDirectiveLoc::Comp(SourceMgr));
  54. assert(low != CondDirectiveLocs.end());
  55. return low->getRegionLoc();
  56. }
  57. void PPConditionalDirectiveRecord::addCondDirectiveLoc(
  58. CondDirectiveLoc DirLoc) {
  59. // Ignore directives in system headers.
  60. if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
  61. return;
  62. assert(CondDirectiveLocs.empty() ||
  63. SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
  64. DirLoc.getLoc()));
  65. CondDirectiveLocs.push_back(DirLoc);
  66. }
  67. void PPConditionalDirectiveRecord::If(SourceLocation Loc,
  68. SourceRange ConditionRange,
  69. ConditionValueKind ConditionValue) {
  70. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  71. CondDirectiveStack.push_back(Loc);
  72. }
  73. void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
  74. const Token &MacroNameTok,
  75. const MacroDefinition &MD) {
  76. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  77. CondDirectiveStack.push_back(Loc);
  78. }
  79. void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
  80. const Token &MacroNameTok,
  81. const MacroDefinition &MD) {
  82. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  83. CondDirectiveStack.push_back(Loc);
  84. }
  85. void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
  86. SourceRange ConditionRange,
  87. ConditionValueKind ConditionValue,
  88. SourceLocation IfLoc) {
  89. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  90. CondDirectiveStack.back() = Loc;
  91. }
  92. void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
  93. SourceLocation IfLoc) {
  94. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  95. CondDirectiveStack.back() = Loc;
  96. }
  97. void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
  98. SourceLocation IfLoc) {
  99. addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
  100. assert(!CondDirectiveStack.empty());
  101. CondDirectiveStack.pop_back();
  102. }
  103. size_t PPConditionalDirectiveRecord::getTotalMemory() const {
  104. return llvm::capacity_in_bytes(CondDirectiveLocs);
  105. }