clang  10.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 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::Else(SourceLocation Loc,
105  SourceLocation IfLoc) {
106  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
107  CondDirectiveStack.back() = Loc;
108 }
109 
110 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
111  SourceLocation IfLoc) {
112  addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
113  assert(!CondDirectiveStack.empty());
114  CondDirectiveStack.pop_back();
115 }
116 
118  return llvm::capacity_in_bytes(CondDirectiveLocs);
119 }
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:1667
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.