blob: b9f68e48293c67c03a53d06d52ede3172afeefcd [file] [log] [blame]
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +00001//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the PPConditionalDirectiveRecord class, which maintains
10// a record of conditional directive regions.
11//
12//===----------------------------------------------------------------------===//
13#include "clang/Lex/PPConditionalDirectiveRecord.h"
14#include "llvm/Support/Capacity.h"
15
16using namespace clang;
17
18PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
19 : SourceMgr(SM) {
20 CondDirectiveStack.push_back(SourceLocation());
21}
22
23bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
24 SourceRange Range) const {
25 if (Range.isInvalid())
26 return false;
27
28 CondDirectiveLocsTy::const_iterator
29 low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
30 Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
31 if (low == CondDirectiveLocs.end())
32 return false;
33
34 if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
35 return false;
36
37 CondDirectiveLocsTy::const_iterator
38 upp = std::upper_bound(low, CondDirectiveLocs.end(),
39 Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
40 SourceLocation uppRegion;
41 if (upp != CondDirectiveLocs.end())
42 uppRegion = upp->getRegionLoc();
43
44 return low->getRegionLoc() != uppRegion;
45}
46
47SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
48 SourceLocation Loc) const {
49 if (Loc.isInvalid())
50 return SourceLocation();
51 if (CondDirectiveLocs.empty())
52 return SourceLocation();
53
54 if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
55 Loc))
56 return CondDirectiveStack.back();
57
58 CondDirectiveLocsTy::const_iterator
59 low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
60 Loc, CondDirectiveLoc::Comp(SourceMgr));
61 assert(low != CondDirectiveLocs.end());
62 return low->getRegionLoc();
63}
64
65void PPConditionalDirectiveRecord::addCondDirectiveLoc(
66 CondDirectiveLoc DirLoc) {
67 // Ignore directives in system headers.
68 if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
69 return;
70
71 assert(CondDirectiveLocs.empty() ||
72 SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
73 DirLoc.getLoc()));
74 CondDirectiveLocs.push_back(DirLoc);
75}
76
77void PPConditionalDirectiveRecord::If(SourceLocation Loc,
John Thompsonb1028562013-07-18 00:00:36 +000078 SourceRange ConditionRange,
John Thompson87f9fef2013-12-07 08:41:15 +000079 ConditionValueKind ConditionValue) {
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +000080 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
81 CondDirectiveStack.push_back(Loc);
82}
83
84void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
Argyrios Kyrtzidis222a7bb2012-12-08 02:21:11 +000085 const Token &MacroNameTok,
Richard Smith36bd40d2015-05-04 03:15:40 +000086 const MacroDefinition &MD) {
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +000087 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
88 CondDirectiveStack.push_back(Loc);
89}
90
91void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
Argyrios Kyrtzidis222a7bb2012-12-08 02:21:11 +000092 const Token &MacroNameTok,
Richard Smith36bd40d2015-05-04 03:15:40 +000093 const MacroDefinition &MD) {
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +000094 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
95 CondDirectiveStack.push_back(Loc);
96}
97
98void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
99 SourceRange ConditionRange,
John Thompson87f9fef2013-12-07 08:41:15 +0000100 ConditionValueKind ConditionValue,
Argyrios Kyrtzidisf3d587e2012-12-04 07:27:05 +0000101 SourceLocation IfLoc) {
102 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
103 CondDirectiveStack.back() = Loc;
104}
105
106void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
107 SourceLocation IfLoc) {
108 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
109 CondDirectiveStack.back() = Loc;
110}
111
112void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
113 SourceLocation IfLoc) {
114 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
115 assert(!CondDirectiveStack.empty());
116 CondDirectiveStack.pop_back();
117}
118
119size_t PPConditionalDirectiveRecord::getTotalMemory() const {
120 return llvm::capacity_in_bytes(CondDirectiveLocs);
121}