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