Home | History | Annotate | Line # | Download | only in Lex
      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:
     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 
     64 public:
     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 
     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 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