Clang Project

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