clang API Documentation

PPConditionalDirectiveRecord.h
Go to the documentation of this file.
00001 //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the PPConditionalDirectiveRecord class, which maintains
00011 //  a record of conditional directive regions.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
00015 #define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
00016 
00017 #include "clang/Basic/SourceLocation.h"
00018 #include "clang/Lex/PPCallbacks.h"
00019 #include "llvm/ADT/SmallVector.h"
00020 #include <vector>
00021 
00022 namespace clang {
00023   
00024 /// \brief Records preprocessor conditional directive regions and allows
00025 /// querying in which region source locations belong to.
00026 class PPConditionalDirectiveRecord : public PPCallbacks {
00027   SourceManager &SourceMgr;
00028   
00029   SmallVector<SourceLocation, 6> CondDirectiveStack;
00030 
00031   class CondDirectiveLoc {
00032     SourceLocation Loc;
00033     SourceLocation RegionLoc;
00034 
00035   public:
00036     CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
00037       : Loc(Loc), RegionLoc(RegionLoc) {}
00038 
00039     SourceLocation getLoc() const { return Loc; }
00040     SourceLocation getRegionLoc() const { return RegionLoc; }
00041 
00042     class Comp {
00043       SourceManager &SM;
00044     public:
00045       explicit Comp(SourceManager &SM) : SM(SM) {}
00046       bool operator()(const CondDirectiveLoc &LHS,
00047                       const CondDirectiveLoc &RHS) {
00048         return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
00049       }
00050       bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
00051         return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
00052       }
00053       bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
00054         return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
00055       }
00056     };
00057   };
00058 
00059   typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
00060   /// \brief The locations of conditional directives in source order.
00061   CondDirectiveLocsTy CondDirectiveLocs;
00062 
00063   void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
00064 
00065 public:
00066   /// \brief Construct a new preprocessing record.
00067   explicit PPConditionalDirectiveRecord(SourceManager &SM);
00068 
00069   size_t getTotalMemory() const;
00070 
00071   SourceManager &getSourceManager() const { return SourceMgr; }
00072 
00073   /// \brief Returns true if the given range intersects with a conditional
00074   /// directive. if a \#if/\#endif block is fully contained within the range,
00075   /// this function will return false.
00076   bool rangeIntersectsConditionalDirective(SourceRange Range) const;
00077 
00078   /// \brief Returns true if the given locations are in different regions,
00079   /// separated by conditional directive blocks.
00080   bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
00081                                                 SourceLocation RHS) const {
00082     return findConditionalDirectiveRegionLoc(LHS) !=
00083         findConditionalDirectiveRegionLoc(RHS);
00084   }
00085 
00086   SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
00087 
00088 private:
00089   void If(SourceLocation Loc, SourceRange ConditionRange,
00090           ConditionValueKind ConditionValue) override;
00091   void Elif(SourceLocation Loc, SourceRange ConditionRange,
00092             ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
00093   void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
00094              const MacroDirective *MD) override;
00095   void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
00096               const MacroDirective *MD) override;
00097   void Else(SourceLocation Loc, SourceLocation IfLoc) override;
00098   void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
00099 };
00100 
00101 } // end namespace clang
00102 
00103 #endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H