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