blob: 12a77849b8b30cb184bb8fb535c2ab9b4748e50c [file] [log] [blame]
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +00001//===--- 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
17using namespace clang;
18
19PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
20 : SourceMgr(SM) {
21 CondDirectiveStack.push_back(SourceLocation());
22}
23
24bool 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
48SourceLocation 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
66void 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
78void PPConditionalDirectiveRecord::If(SourceLocation Loc,
John Thompsonb1028562013-07-18 00:00:36 +000079 SourceRange ConditionRange,
John Thompson87f9fef2013-12-07 08:41:15 +000080 ConditionValueKind ConditionValue) {
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +000081 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
82 CondDirectiveStack.push_back(Loc);
83}
84
85void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
Argyrios Kyrtzidis222a7bb2012-12-08 02:21:11 +000086 const Token &MacroNameTok,
Richard Smith36bd40d2015-05-04 03:15:40 +000087 const MacroDefinition &MD) {
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +000088 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
89 CondDirectiveStack.push_back(Loc);
90}
91
92void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
Argyrios Kyrtzidis222a7bb2012-12-08 02:21:11 +000093 const Token &MacroNameTok,
Richard Smith36bd40d2015-05-04 03:15:40 +000094 const MacroDefinition &MD) {
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +000095 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
96 CondDirectiveStack.push_back(Loc);
97}
98
99void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
100 SourceRange ConditionRange,
John Thompson87f9fef2013-12-07 08:41:15 +0000101 ConditionValueKind ConditionValue,
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +0000102 SourceLocation IfLoc) {
103 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
104 CondDirectiveStack.back() = Loc;
105}
106
107void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
108 SourceLocation IfLoc) {
109 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
110 CondDirectiveStack.back() = Loc;
111}
112
113void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
114 SourceLocation IfLoc) {
115 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
116 assert(!CondDirectiveStack.empty());
117 CondDirectiveStack.pop_back();
118}
119
120size_t PPConditionalDirectiveRecord::getTotalMemory() const {
121 return llvm::capacity_in_bytes(CondDirectiveLocs);
122}