clang  6.0.0svn
PPConditionalDirectiveRecord.cpp
Go to the documentation of this file.
1 //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the PPConditionalDirectiveRecord class, which maintains
11 // a record of conditional directive regions.
12 //
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Support/Capacity.h"
16 
17 using namespace clang;
18 
20  : SourceMgr(SM) {
21  CondDirectiveStack.push_back(SourceLocation());
22 }
23 
25  SourceRange Range) const {
26  if (Range.isInvalid())
27  return false;
28 
29  CondDirectiveLocsTy::const_iterator
30  low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
31  Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
32  if (low == CondDirectiveLocs.end())
33  return false;
34 
35  if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
36  return false;
37 
38  CondDirectiveLocsTy::const_iterator
39  upp = std::upper_bound(low, CondDirectiveLocs.end(),
40  Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
41  SourceLocation uppRegion;
42  if (upp != CondDirectiveLocs.end())
43  uppRegion = upp->getRegionLoc();
44 
45  return low->getRegionLoc() != uppRegion;
46 }
47 
49  SourceLocation Loc) const {
50  if (Loc.isInvalid())
51  return SourceLocation();
52  if (CondDirectiveLocs.empty())
53  return SourceLocation();
54 
55  if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
56  Loc))
57  return CondDirectiveStack.back();
58 
59  CondDirectiveLocsTy::const_iterator
60  low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
61  Loc, CondDirectiveLoc::Comp(SourceMgr));
62  assert(low != CondDirectiveLocs.end());
63  return low->getRegionLoc();
64 }
65 
66 void PPConditionalDirectiveRecord::addCondDirectiveLoc(
67  CondDirectiveLoc DirLoc) {
68  // Ignore directives in system headers.
69  if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
70  return;
71 
72  assert(CondDirectiveLocs.empty() ||
73  SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
74  DirLoc.getLoc()));
75  CondDirectiveLocs.push_back(DirLoc);
76 }
77 
78 void PPConditionalDirectiveRecord::If(SourceLocation Loc,
79  SourceRange ConditionRange,
80  ConditionValueKind ConditionValue) {
81  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
82  CondDirectiveStack.push_back(Loc);
83 }
84 
85 void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
86  const Token &MacroNameTok,
87  const MacroDefinition &MD) {
88  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
89  CondDirectiveStack.push_back(Loc);
90 }
91 
92 void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
93  const Token &MacroNameTok,
94  const MacroDefinition &MD) {
95  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
96  CondDirectiveStack.push_back(Loc);
97 }
98 
99 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
100  SourceRange ConditionRange,
101  ConditionValueKind ConditionValue,
102  SourceLocation IfLoc) {
103  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
104  CondDirectiveStack.back() = Loc;
105 }
106 
107 void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
108  SourceLocation IfLoc) {
109  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
110  CondDirectiveStack.back() = Loc;
111 }
112 
113 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
114  SourceLocation IfLoc) {
115  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
116  assert(!CondDirectiveStack.empty());
117  CondDirectiveStack.pop_back();
118 }
119 
121  return llvm::capacity_in_bytes(CondDirectiveLocs);
122 }
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:545
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
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:1308
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.