diff options
Diffstat (limited to 'include/clang/Lex/PPConditionalDirectiveRecord.h')
-rw-r--r-- | include/clang/Lex/PPConditionalDirectiveRecord.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h new file mode 100644 index 0000000..b9a2252 --- /dev/null +++ b/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -0,0 +1,102 @@ +//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PPConditionalDirectiveRecord class, which maintains +// a record of conditional directive regions. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H +#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H + +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/PPCallbacks.h" +#include "llvm/ADT/SmallVector.h" +#include <vector> + +namespace clang { + +/// \brief Records preprocessor conditional directive regions and allows +/// querying in which region source locations belong to. +class PPConditionalDirectiveRecord : public PPCallbacks { + SourceManager &SourceMgr; + + SmallVector<SourceLocation, 6> CondDirectiveStack; + + class CondDirectiveLoc { + SourceLocation Loc; + SourceLocation RegionLoc; + + public: + CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc) + : Loc(Loc), RegionLoc(RegionLoc) {} + + SourceLocation getLoc() const { return Loc; } + SourceLocation getRegionLoc() const { return RegionLoc; } + + class Comp { + SourceManager &SM; + public: + explicit Comp(SourceManager &SM) : SM(SM) {} + bool operator()(const CondDirectiveLoc &LHS, + const CondDirectiveLoc &RHS) { + return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc()); + } + bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) { + return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS); + } + bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) { + return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc()); + } + }; + }; + + typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy; + /// \brief The locations of conditional directives in source order. + CondDirectiveLocsTy CondDirectiveLocs; + + void addCondDirectiveLoc(CondDirectiveLoc DirLoc); + +public: + /// \brief Construct a new preprocessing record. + explicit PPConditionalDirectiveRecord(SourceManager &SM); + + size_t getTotalMemory() const; + + SourceManager &getSourceManager() const { return SourceMgr; } + + /// \brief Returns true if the given range intersects with a conditional + /// directive. if a \#if/\#endif block is fully contained within the range, + /// this function will return false. + bool rangeIntersectsConditionalDirective(SourceRange Range) const; + + /// \brief Returns true if the given locations are in different regions, + /// separated by conditional directive blocks. + bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS, + SourceLocation RHS) const { + return findConditionalDirectiveRegionLoc(LHS) != + findConditionalDirectiveRegionLoc(RHS); + } + + SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const; + +private: + virtual void If(SourceLocation Loc, SourceRange ConditionRange); + virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, + SourceLocation IfLoc); + virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, + const MacroDirective *MD); + virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, + const MacroDirective *MD); + virtual void Else(SourceLocation Loc, SourceLocation IfLoc); + virtual void Endif(SourceLocation Loc, SourceLocation IfLoc); +}; + +} // end namespace clang + +#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H |