clang API Documentation
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