1 //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the PPConditionalDirectiveRecord class, which maintains
11 // a record of conditional directive regions.
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
15 #define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
17 #include "clang/Basic/SourceLocation.h"
18 #include "clang/Lex/PPCallbacks.h"
19 #include "llvm/ADT/SmallVector.h"
24 /// \brief Records preprocessor conditional directive regions and allows
25 /// querying in which region source locations belong to.
26 class PPConditionalDirectiveRecord : public PPCallbacks {
27 SourceManager &SourceMgr;
29 SmallVector<SourceLocation, 6> CondDirectiveStack;
31 class CondDirectiveLoc {
33 SourceLocation RegionLoc;
36 CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
37 : Loc(Loc), RegionLoc(RegionLoc) {}
39 SourceLocation getLoc() const { return Loc; }
40 SourceLocation getRegionLoc() const { return RegionLoc; }
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());
50 bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
51 return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
53 bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
54 return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
59 typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
60 /// \brief The locations of conditional directives in source order.
61 CondDirectiveLocsTy CondDirectiveLocs;
63 void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
66 /// \brief Construct a new preprocessing record.
67 explicit PPConditionalDirectiveRecord(SourceManager &SM);
69 size_t getTotalMemory() const;
71 SourceManager &getSourceManager() const { return SourceMgr; }
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;
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);
86 SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
89 virtual void If(SourceLocation Loc, SourceRange ConditionRange);
90 virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
91 SourceLocation IfLoc);
92 virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
93 const MacroDirective *MD);
94 virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
95 const MacroDirective *MD);
96 virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
97 virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
100 } // end namespace clang
102 #endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H