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.getLoc(), RHS.getLoc()); 48 } 49 bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) { 50 return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS); 51 } 52 bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) { 53 return SM.isBeforeInTranslationUnit(LHS, 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(LHS) != 82 findConditionalDirectiveRegionLoc(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 Else(SourceLocation Loc, SourceLocation IfLoc) override; 97 void Endif(SourceLocation Loc, SourceLocation IfLoc) override; 98}; 99 100} // end namespace clang 101 102#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H 103