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 21 namespace clang { 22 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; 27 28 SmallVector<SourceLocation, 6> CondDirectiveStack; 29 30 class CondDirectiveLoc { 31 SourceLocation Loc; 32 SourceLocation RegionLoc; 33 34 public: CondDirectiveLoc(SourceLocation Loc,SourceLocation RegionLoc)35 CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc) 36 : Loc(Loc), RegionLoc(RegionLoc) {} 37 getLoc()38 SourceLocation getLoc() const { return Loc; } getRegionLoc()39 SourceLocation getRegionLoc() const { return RegionLoc; } 40 41 class Comp { 42 SourceManager &SM; 43 public: Comp(SourceManager & SM)44 explicit Comp(SourceManager &SM) : SM(SM) {} operator()45 bool operator()(const CondDirectiveLoc &LHS, 46 const CondDirectiveLoc &RHS) { 47 return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc()); 48 } operator()49 bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) { 50 return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS); 51 } operator()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 64 public: 65 /// Construct a new preprocessing record. 66 explicit PPConditionalDirectiveRecord(SourceManager &SM); 67 68 size_t getTotalMemory() const; 69 getSourceManager()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. areInDifferentConditionalDirectiveRegion(SourceLocation LHS,SourceLocation RHS)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 87 private: 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