]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / clang / lib / Lex / PPConditionalDirectiveRecord.cpp
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 //===----------------------------------------------------------------------===//
14 #include "clang/Lex/PPConditionalDirectiveRecord.h"
15 #include "llvm/Support/Capacity.h"
16
17 using namespace clang;
18
19 PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
20   : SourceMgr(SM) {
21   CondDirectiveStack.push_back(SourceLocation());
22 }
23
24 bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
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
48 SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
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                                       bool 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 MacroDirective *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 MacroDirective *MD) {
95   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
96   CondDirectiveStack.push_back(Loc);
97 }
98
99 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
100                                         SourceRange ConditionRange,
101                                         bool 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
120 size_t PPConditionalDirectiveRecord::getTotalMemory() const {
121   return llvm::capacity_in_bytes(CondDirectiveLocs);
122 }