]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/llvm/tools/clang/lib/Lex/PPConditionalDirectiveRecord.cpp
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.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   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
81   CondDirectiveStack.push_back(Loc);
82 }
83
84 void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
85                                          const Token &MacroNameTok,
86                                          const MacroDirective *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 MacroDirective *MD) {
94   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
95   CondDirectiveStack.push_back(Loc);
96 }
97
98 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
99                                         SourceRange ConditionRange,
100                                         SourceLocation IfLoc) {
101   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
102   CondDirectiveStack.back() = Loc;
103 }
104
105 void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
106                                         SourceLocation IfLoc) {
107   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
108   CondDirectiveStack.back() = Loc;
109 }
110
111 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
112                                          SourceLocation IfLoc) {
113   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
114   assert(!CondDirectiveStack.empty());
115   CondDirectiveStack.pop_back();
116 }
117
118 size_t PPConditionalDirectiveRecord::getTotalMemory() const {
119   return llvm::capacity_in_bytes(CondDirectiveLocs);
120 }