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