1 //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the PPConditionalDirectiveRecord class, which maintains
10 // a record of conditional directive regions.
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
14 #define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
16 #include "clang/Basic/SourceLocation.h"
17 #include "clang/Lex/PPCallbacks.h"
18 #include "llvm/ADT/SmallVector.h"
23 /// Records preprocessor conditional directive regions and allows
24 /// querying in which region source locations belong to.
25 class PPConditionalDirectiveRecord : public PPCallbacks {
26 SourceManager &SourceMgr;
28 SmallVector<SourceLocation, 6> CondDirectiveStack;
30 class CondDirectiveLoc {
32 SourceLocation RegionLoc;
35 CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
36 : Loc(Loc), RegionLoc(RegionLoc) {}
38 SourceLocation getLoc() const { return Loc; }
39 SourceLocation getRegionLoc() const { return RegionLoc; }
44 explicit Comp(SourceManager &SM) : SM(SM) {}
45 bool operator()(const CondDirectiveLoc &LHS,
46 const CondDirectiveLoc &RHS) {
47 return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
49 bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
50 return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
52 bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
53 return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
58 typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
59 /// The locations of conditional directives in source order.
60 CondDirectiveLocsTy CondDirectiveLocs;
62 void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
65 /// Construct a new preprocessing record.
66 explicit PPConditionalDirectiveRecord(SourceManager &SM);
68 size_t getTotalMemory() const;
70 SourceManager &getSourceManager() const { return SourceMgr; }
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;
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(LHS) !=
82 findConditionalDirectiveRegionLoc(RHS);
85 SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
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 Else(SourceLocation Loc, SourceLocation IfLoc) override;
97 void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
100 } // end namespace clang
102 #endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H