llvm-project
141 строка · 5.6 Кб
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
16using namespace clang;
17
18PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
19: SourceMgr(SM) {
20CondDirectiveStack.push_back(SourceLocation());
21}
22
23bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
24SourceRange Range) const {
25if (Range.isInvalid())
26return false;
27
28CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
29CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
30if (low == CondDirectiveLocs.end())
31return false;
32
33if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
34return false;
35
36CondDirectiveLocsTy::const_iterator
37upp = std::upper_bound(low, CondDirectiveLocs.end(),
38Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
39SourceLocation uppRegion;
40if (upp != CondDirectiveLocs.end())
41uppRegion = upp->getRegionLoc();
42
43return low->getRegionLoc() != uppRegion;
44}
45
46SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
47SourceLocation Loc) const {
48if (Loc.isInvalid())
49return SourceLocation();
50if (CondDirectiveLocs.empty())
51return SourceLocation();
52
53if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
54Loc))
55return CondDirectiveStack.back();
56
57CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
58CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));
59assert(low != CondDirectiveLocs.end());
60return low->getRegionLoc();
61}
62
63void PPConditionalDirectiveRecord::addCondDirectiveLoc(
64CondDirectiveLoc DirLoc) {
65// Ignore directives in system headers.
66if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
67return;
68
69assert(CondDirectiveLocs.empty() ||
70SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
71DirLoc.getLoc()));
72CondDirectiveLocs.push_back(DirLoc);
73}
74
75void PPConditionalDirectiveRecord::If(SourceLocation Loc,
76SourceRange ConditionRange,
77ConditionValueKind ConditionValue) {
78addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
79CondDirectiveStack.push_back(Loc);
80}
81
82void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
83const Token &MacroNameTok,
84const MacroDefinition &MD) {
85addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
86CondDirectiveStack.push_back(Loc);
87}
88
89void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
90const Token &MacroNameTok,
91const MacroDefinition &MD) {
92addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
93CondDirectiveStack.push_back(Loc);
94}
95
96void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
97SourceRange ConditionRange,
98ConditionValueKind ConditionValue,
99SourceLocation IfLoc) {
100addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
101CondDirectiveStack.back() = Loc;
102}
103
104void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, const Token &,
105const MacroDefinition &) {
106addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
107CondDirectiveStack.back() = Loc;
108}
109void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,
110SourceLocation) {
111addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
112CondDirectiveStack.back() = Loc;
113}
114
115void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,
116const MacroDefinition &) {
117addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
118CondDirectiveStack.back() = Loc;
119}
120void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,
121SourceLocation) {
122addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
123CondDirectiveStack.back() = Loc;
124}
125
126void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
127SourceLocation IfLoc) {
128addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
129CondDirectiveStack.back() = Loc;
130}
131
132void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
133SourceLocation IfLoc) {
134addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
135assert(!CondDirectiveStack.empty());
136CondDirectiveStack.pop_back();
137}
138
139size_t PPConditionalDirectiveRecord::getTotalMemory() const {
140return llvm::capacity_in_bytes(CondDirectiveLocs);
141}
142