1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the PPConditionalDirectiveRecord class, which maintains
// a record of conditional directive regions.
//
//===----------------------------------------------------------------------===//
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "llvm/Support/Capacity.h"
using namespace clang;
PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
: SourceMgr(SM) {
CondDirectiveStack.push_back(SourceLocation());
}
bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
SourceRange Range) const {
if (Range.isInvalid())
return false;
CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
if (low == CondDirectiveLocs.end())
return false;
if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
return false;
CondDirectiveLocsTy::const_iterator
upp = std::upper_bound(low, CondDirectiveLocs.end(),
Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
SourceLocation uppRegion;
if (upp != CondDirectiveLocs.end())
uppRegion = upp->getRegionLoc();
return low->getRegionLoc() != uppRegion;
}
SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
SourceLocation Loc) const {
if (Loc.isInvalid())
return SourceLocation();
if (CondDirectiveLocs.empty())
return SourceLocation();
if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
Loc))
return CondDirectiveStack.back();
CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));
assert(low != CondDirectiveLocs.end());
return low->getRegionLoc();
}
void PPConditionalDirectiveRecord::addCondDirectiveLoc(
CondDirectiveLoc DirLoc) {
// Ignore directives in system headers.
if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
return;
assert(CondDirectiveLocs.empty() ||
SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
DirLoc.getLoc()));
CondDirectiveLocs.push_back(DirLoc);
}
void PPConditionalDirectiveRecord::If(SourceLocation Loc,
SourceRange ConditionRange,
ConditionValueKind ConditionValue) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.push_back(Loc);
}
void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
const Token &MacroNameTok,
const MacroDefinition &MD) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.push_back(Loc);
}
void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
const Token &MacroNameTok,
const MacroDefinition &MD) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.push_back(Loc);
}
void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
SourceRange ConditionRange,
ConditionValueKind ConditionValue,
SourceLocation IfLoc) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.back() = Loc;
}
void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, const Token &,
const MacroDefinition &) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.back() = Loc;
}
void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,
SourceLocation) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.back() = Loc;
}
void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,
const MacroDefinition &) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.back() = Loc;
}
void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,
SourceLocation) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.back() = Loc;
}
void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
SourceLocation IfLoc) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.back() = Loc;
}
void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
SourceLocation IfLoc) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
assert(!CondDirectiveStack.empty());
CondDirectiveStack.pop_back();
}
size_t PPConditionalDirectiveRecord::getTotalMemory() const {
return llvm::capacity_in_bytes(CondDirectiveLocs);
}
|