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