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