1f3d587eaSArgyrios Kyrtzidis //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
2f3d587eaSArgyrios Kyrtzidis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f3d587eaSArgyrios Kyrtzidis //
7f3d587eaSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
8f3d587eaSArgyrios Kyrtzidis //
9f3d587eaSArgyrios Kyrtzidis // This file implements the PPConditionalDirectiveRecord class, which maintains
10f3d587eaSArgyrios Kyrtzidis // a record of conditional directive regions.
11f3d587eaSArgyrios Kyrtzidis //
12f3d587eaSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
13f3d587eaSArgyrios Kyrtzidis #include "clang/Lex/PPConditionalDirectiveRecord.h"
14f3d587eaSArgyrios Kyrtzidis #include "llvm/Support/Capacity.h"
15f3d587eaSArgyrios Kyrtzidis
16f3d587eaSArgyrios Kyrtzidis using namespace clang;
17f3d587eaSArgyrios Kyrtzidis
PPConditionalDirectiveRecord(SourceManager & SM)18f3d587eaSArgyrios Kyrtzidis PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
19f3d587eaSArgyrios Kyrtzidis : SourceMgr(SM) {
20f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.push_back(SourceLocation());
21f3d587eaSArgyrios Kyrtzidis }
22f3d587eaSArgyrios Kyrtzidis
rangeIntersectsConditionalDirective(SourceRange Range) const23f3d587eaSArgyrios Kyrtzidis bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
24f3d587eaSArgyrios Kyrtzidis SourceRange Range) const {
25f3d587eaSArgyrios Kyrtzidis if (Range.isInvalid())
26f3d587eaSArgyrios Kyrtzidis return false;
27f3d587eaSArgyrios Kyrtzidis
287264a474SFangrui Song CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
297264a474SFangrui Song CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
30f3d587eaSArgyrios Kyrtzidis if (low == CondDirectiveLocs.end())
31f3d587eaSArgyrios Kyrtzidis return false;
32f3d587eaSArgyrios Kyrtzidis
33f3d587eaSArgyrios Kyrtzidis if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
34f3d587eaSArgyrios Kyrtzidis return false;
35f3d587eaSArgyrios Kyrtzidis
36f3d587eaSArgyrios Kyrtzidis CondDirectiveLocsTy::const_iterator
37f3d587eaSArgyrios Kyrtzidis upp = std::upper_bound(low, CondDirectiveLocs.end(),
38f3d587eaSArgyrios Kyrtzidis Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
39f3d587eaSArgyrios Kyrtzidis SourceLocation uppRegion;
40f3d587eaSArgyrios Kyrtzidis if (upp != CondDirectiveLocs.end())
41f3d587eaSArgyrios Kyrtzidis uppRegion = upp->getRegionLoc();
42f3d587eaSArgyrios Kyrtzidis
43f3d587eaSArgyrios Kyrtzidis return low->getRegionLoc() != uppRegion;
44f3d587eaSArgyrios Kyrtzidis }
45f3d587eaSArgyrios Kyrtzidis
findConditionalDirectiveRegionLoc(SourceLocation Loc) const46f3d587eaSArgyrios Kyrtzidis SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
47f3d587eaSArgyrios Kyrtzidis SourceLocation Loc) const {
48f3d587eaSArgyrios Kyrtzidis if (Loc.isInvalid())
49f3d587eaSArgyrios Kyrtzidis return SourceLocation();
50f3d587eaSArgyrios Kyrtzidis if (CondDirectiveLocs.empty())
51f3d587eaSArgyrios Kyrtzidis return SourceLocation();
52f3d587eaSArgyrios Kyrtzidis
53f3d587eaSArgyrios Kyrtzidis if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
54f3d587eaSArgyrios Kyrtzidis Loc))
55f3d587eaSArgyrios Kyrtzidis return CondDirectiveStack.back();
56f3d587eaSArgyrios Kyrtzidis
577264a474SFangrui Song CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
587264a474SFangrui Song CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));
59f3d587eaSArgyrios Kyrtzidis assert(low != CondDirectiveLocs.end());
60f3d587eaSArgyrios Kyrtzidis return low->getRegionLoc();
61f3d587eaSArgyrios Kyrtzidis }
62f3d587eaSArgyrios Kyrtzidis
addCondDirectiveLoc(CondDirectiveLoc DirLoc)63f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::addCondDirectiveLoc(
64f3d587eaSArgyrios Kyrtzidis CondDirectiveLoc DirLoc) {
65f3d587eaSArgyrios Kyrtzidis // Ignore directives in system headers.
66f3d587eaSArgyrios Kyrtzidis if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
67f3d587eaSArgyrios Kyrtzidis return;
68f3d587eaSArgyrios Kyrtzidis
69f3d587eaSArgyrios Kyrtzidis assert(CondDirectiveLocs.empty() ||
70f3d587eaSArgyrios Kyrtzidis SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
71f3d587eaSArgyrios Kyrtzidis DirLoc.getLoc()));
72f3d587eaSArgyrios Kyrtzidis CondDirectiveLocs.push_back(DirLoc);
73f3d587eaSArgyrios Kyrtzidis }
74f3d587eaSArgyrios Kyrtzidis
If(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue)75f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::If(SourceLocation Loc,
76b102856bSJohn Thompson SourceRange ConditionRange,
7787f9fef5SJohn Thompson ConditionValueKind ConditionValue) {
78f3d587eaSArgyrios Kyrtzidis addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
79f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.push_back(Loc);
80f3d587eaSArgyrios Kyrtzidis }
81f3d587eaSArgyrios Kyrtzidis
Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)82f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
83222a7bbfSArgyrios Kyrtzidis const Token &MacroNameTok,
8436bd40dfSRichard Smith const MacroDefinition &MD) {
85f3d587eaSArgyrios Kyrtzidis addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
86f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.push_back(Loc);
87f3d587eaSArgyrios Kyrtzidis }
88f3d587eaSArgyrios Kyrtzidis
Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)89f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
90222a7bbfSArgyrios Kyrtzidis const Token &MacroNameTok,
9136bd40dfSRichard Smith const MacroDefinition &MD) {
92f3d587eaSArgyrios Kyrtzidis addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
93f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.push_back(Loc);
94f3d587eaSArgyrios Kyrtzidis }
95f3d587eaSArgyrios Kyrtzidis
Elif(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue,SourceLocation IfLoc)96f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
97f3d587eaSArgyrios Kyrtzidis SourceRange ConditionRange,
9887f9fef5SJohn Thompson ConditionValueKind ConditionValue,
99f3d587eaSArgyrios Kyrtzidis SourceLocation IfLoc) {
100f3d587eaSArgyrios Kyrtzidis addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
101f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.back() = Loc;
102f3d587eaSArgyrios Kyrtzidis }
103f3d587eaSArgyrios Kyrtzidis
Elifdef(SourceLocation Loc,const Token &,const MacroDefinition &)104*8edd3464SAaron Ballman void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, const Token &,
105*8edd3464SAaron Ballman const MacroDefinition &) {
106*8edd3464SAaron Ballman addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
107*8edd3464SAaron Ballman CondDirectiveStack.back() = Loc;
108*8edd3464SAaron Ballman }
Elifdef(SourceLocation Loc,SourceRange,SourceLocation)109*8edd3464SAaron Ballman void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,
110*8edd3464SAaron Ballman SourceLocation) {
111*8edd3464SAaron Ballman addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
112*8edd3464SAaron Ballman CondDirectiveStack.back() = Loc;
113*8edd3464SAaron Ballman }
114*8edd3464SAaron Ballman
Elifndef(SourceLocation Loc,const Token &,const MacroDefinition &)115*8edd3464SAaron Ballman void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,
116*8edd3464SAaron Ballman const MacroDefinition &) {
117*8edd3464SAaron Ballman addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
118*8edd3464SAaron Ballman CondDirectiveStack.back() = Loc;
119*8edd3464SAaron Ballman }
Elifndef(SourceLocation Loc,SourceRange,SourceLocation)120*8edd3464SAaron Ballman void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,
121*8edd3464SAaron Ballman SourceLocation) {
122*8edd3464SAaron Ballman addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
123*8edd3464SAaron Ballman CondDirectiveStack.back() = Loc;
124*8edd3464SAaron Ballman }
125*8edd3464SAaron Ballman
Else(SourceLocation Loc,SourceLocation IfLoc)126f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
127f3d587eaSArgyrios Kyrtzidis SourceLocation IfLoc) {
128f3d587eaSArgyrios Kyrtzidis addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
129f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.back() = Loc;
130f3d587eaSArgyrios Kyrtzidis }
131f3d587eaSArgyrios Kyrtzidis
Endif(SourceLocation Loc,SourceLocation IfLoc)132f3d587eaSArgyrios Kyrtzidis void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
133f3d587eaSArgyrios Kyrtzidis SourceLocation IfLoc) {
134f3d587eaSArgyrios Kyrtzidis addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
135f3d587eaSArgyrios Kyrtzidis assert(!CondDirectiveStack.empty());
136f3d587eaSArgyrios Kyrtzidis CondDirectiveStack.pop_back();
137f3d587eaSArgyrios Kyrtzidis }
138f3d587eaSArgyrios Kyrtzidis
getTotalMemory() const139f3d587eaSArgyrios Kyrtzidis size_t PPConditionalDirectiveRecord::getTotalMemory() const {
140f3d587eaSArgyrios Kyrtzidis return llvm::capacity_in_bytes(CondDirectiveLocs);
141f3d587eaSArgyrios Kyrtzidis }
142