clang  19.0.0git
PPConditionalDirectiveRecord.cpp
Go to the documentation of this file.
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 //===----------------------------------------------------------------------===//
14 #include "llvm/Support/Capacity.h"
15 
16 using namespace clang;
17 
19  : SourceMgr(SM) {
20  CondDirectiveStack.push_back(SourceLocation());
21 }
22 
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 
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::Elifdef(SourceLocation Loc, const Token &,
105  const MacroDefinition &) {
106  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
107  CondDirectiveStack.back() = Loc;
108 }
109 void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,
110  SourceLocation) {
111  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
112  CondDirectiveStack.back() = Loc;
113 }
114 
115 void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,
116  const MacroDefinition &) {
117  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
118  CondDirectiveStack.back() = Loc;
119 }
120 void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,
121  SourceLocation) {
122  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
123  CondDirectiveStack.back() = Loc;
124 }
125 
126 void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
127  SourceLocation IfLoc) {
128  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
129  CondDirectiveStack.back() = Loc;
130 }
131 
132 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
133  SourceLocation IfLoc) {
134  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
135  assert(!CondDirectiveStack.empty());
136  CondDirectiveStack.pop_back();
137 }
138 
140  return llvm::capacity_in_bytes(CondDirectiveLocs);
141 }
#define SM(sm)
Definition: Cuda.cpp:83
SourceRange Range
Definition: SemaObjC.cpp:754
SourceLocation Loc
Definition: SemaObjC.cpp:755
A description of the current definition of a macro.
Definition: MacroInfo.h:590
PPConditionalDirectiveRecord(SourceManager &SM)
Construct a new preprocessing record.
bool rangeIntersectsConditionalDirective(SourceRange Range) const
Returns true if the given range intersects with a conditional directive.
SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const
Encodes a location in the source.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
A trivial tuple used to represent a source range.
bool isInvalid() const
SourceLocation getEnd() const
SourceLocation getBegin() const
Token - This structure provides full information about a lexed token.
Definition: Token.h:36
The JSON file list parser is used to communicate input to InstallAPI.