1//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the PPConditionalDirectiveRecord class, which maintains
10// a record of conditional directive regions.
11//
12//===----------------------------------------------------------------------===//
13#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
14#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
15
16#include "clang/Basic/SourceLocation.h"
17#include "clang/Lex/PPCallbacks.h"
18#include "llvm/ADT/SmallVector.h"
19#include <vector>
20
21namespace clang {
22
23/// Records preprocessor conditional directive regions and allows
24/// querying in which region source locations belong to.
25class PPConditionalDirectiveRecord : public PPCallbacks {
26 SourceManager &SourceMgr;
27
28 SmallVector<SourceLocation, 6> CondDirectiveStack;
29
30 class CondDirectiveLoc {
31 SourceLocation Loc;
32 SourceLocation RegionLoc;
33
34 public:
35 CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
36 : Loc(Loc), RegionLoc(RegionLoc) {}
37
38 SourceLocation getLoc() const { return Loc; }
39 SourceLocation getRegionLoc() const { return RegionLoc; }
40
41 class Comp {
42 SourceManager &SM;
43 public:
44 explicit Comp(SourceManager &SM) : SM(SM) {}
45 bool operator()(const CondDirectiveLoc &LHS,
46 const CondDirectiveLoc &RHS) {
47 return SM.isBeforeInTranslationUnit(LHS: LHS.getLoc(), RHS: RHS.getLoc());
48 }
49 bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
50 return SM.isBeforeInTranslationUnit(LHS: LHS.getLoc(), RHS);
51 }
52 bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
53 return SM.isBeforeInTranslationUnit(LHS, RHS: RHS.getLoc());
54 }
55 };
56 };
57
58 typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
59 /// The locations of conditional directives in source order.
60 CondDirectiveLocsTy CondDirectiveLocs;
61
62 void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
63
64public:
65 /// Construct a new preprocessing record.
66 explicit PPConditionalDirectiveRecord(SourceManager &SM);
67
68 size_t getTotalMemory() const;
69
70 SourceManager &getSourceManager() const { return SourceMgr; }
71
72 /// Returns true if the given range intersects with a conditional
73 /// directive. if a \#if/\#endif block is fully contained within the range,
74 /// this function will return false.
75 bool rangeIntersectsConditionalDirective(SourceRange Range) const;
76
77 /// Returns true if the given locations are in different regions,
78 /// separated by conditional directive blocks.
79 bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
80 SourceLocation RHS) const {
81 return findConditionalDirectiveRegionLoc(Loc: LHS) !=
82 findConditionalDirectiveRegionLoc(Loc: RHS);
83 }
84
85 SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
86
87private:
88 void If(SourceLocation Loc, SourceRange ConditionRange,
89 ConditionValueKind ConditionValue) override;
90 void Elif(SourceLocation Loc, SourceRange ConditionRange,
91 ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
92 void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
93 const MacroDefinition &MD) override;
94 void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
95 const MacroDefinition &MD) override;
96 void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
97 const MacroDefinition &MD) override;
98 void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
99 SourceLocation IfLoc) override;
100 void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
101 const MacroDefinition &MD) override;
102 void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
103 SourceLocation IfLoc) override;
104 void Else(SourceLocation Loc, SourceLocation IfLoc) override;
105 void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
106};
107
108} // end namespace clang
109
110#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
111

source code of clang/include/clang/Lex/PPConditionalDirectiveRecord.h