clang  9.0.0svn
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
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 
48  SourceLocation Loc) const {
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  Loc, CondDirectiveLoc::Comp(SourceMgr));
61  assert(low != CondDirectiveLocs.end());
62  return low->getRegionLoc();
63 }
64 
65 void 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 
77 void PPConditionalDirectiveRecord::If(SourceLocation Loc,
78  SourceRange ConditionRange,
79  ConditionValueKind ConditionValue) {
80  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
81  CondDirectiveStack.push_back(Loc);
82 }
83 
84 void 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 
91 void 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 
98 void 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 
106 void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
107  SourceLocation IfLoc) {
108  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
109  CondDirectiveStack.back() = Loc;
110 }
111 
112 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
113  SourceLocation IfLoc) {
114  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
115  assert(!CondDirectiveStack.empty());
116  CondDirectiveStack.pop_back();
117 }
118 
120  return llvm::capacity_in_bytes(CondDirectiveLocs);
121 }
PPConditionalDirectiveRecord(SourceManager &SM)
Construct a new preprocessing record.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
A description of the current definition of a macro.
Definition: MacroInfo.h:564
Token - This structure provides full information about a lexed token.
Definition: Token.h:34
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isInvalid() const
SourceLocation getEnd() const
const SourceManager & SM
Definition: Format.cpp:1568
Encodes a location in the source.
bool rangeIntersectsConditionalDirective(SourceRange Range) const
Returns true if the given range intersects with a conditional directive.
Dataflow Directional Tag Classes.
SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.