diff options
Diffstat (limited to 'include/clang/Lex/PreprocessingRecord.h')
-rw-r--r-- | include/clang/Lex/PreprocessingRecord.h | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index a778bbe031..587c2a7298 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -17,6 +17,7 @@ #include "clang/Lex/PPCallbacks.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/IdentifierTable.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Allocator.h" @@ -299,6 +300,44 @@ namespace clang { /// and are referenced by the iterator using negative indices. std::vector<PreprocessedEntity *> LoadedPreprocessedEntities; + bool RecordCondDirectives; + unsigned CondDirectiveNextIdx; + SmallVector<unsigned, 6> CondDirectiveStack; + + class CondDirectiveLoc { + SourceLocation Loc; + unsigned Idx; + + public: + CondDirectiveLoc(SourceLocation Loc, unsigned Idx) : Loc(Loc), Idx(Idx) {} + + SourceLocation getLoc() const { return Loc; } + unsigned getIdx() const { return Idx; } + + 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); + unsigned findCondDirectiveIdx(SourceLocation Loc) const; + /// \brief Global (loaded or local) ID for a preprocessed entity. /// Negative values are used to indicate preprocessed entities /// loaded from the external source while non-negative values are used to @@ -349,7 +388,7 @@ namespace clang { public: /// \brief Construct a new preprocessing record. - explicit PreprocessingRecord(SourceManager &SM); + PreprocessingRecord(SourceManager &SM, bool RecordConditionalDirectives); /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { @@ -517,7 +556,25 @@ namespace clang { /// \brief Add a new preprocessed entity to this record. void addPreprocessedEntity(PreprocessedEntity *Entity); - + + /// \brief Returns true if this PreprocessingRecord is keeping track of + /// conditional directives locations. + bool isRecordingConditionalDirectives() const { + return RecordCondDirectives; + } + + /// \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 findCondDirectiveIdx(LHS) != findCondDirectiveIdx(RHS); + } + /// \brief Set the external source for preprocessed entities. void SetExternalSource(ExternalPreprocessingRecordSource &Source); @@ -530,6 +587,7 @@ namespace clang { /// \c MacroInfo. MacroDefinition *findMacroDefinition(const MacroInfo *MI); + private: virtual void MacroExpands(const Token &Id, const MacroInfo* MI, SourceRange Range); virtual void MacroDefined(const Token &Id, const MacroInfo *MI); @@ -542,8 +600,14 @@ namespace clang { SourceLocation EndLoc, StringRef SearchPath, StringRef RelativePath); + virtual void If(SourceLocation Loc, SourceRange ConditionRange); + virtual void Elif(SourceLocation Loc, SourceRange ConditionRange, + SourceLocation IfLoc); + virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok); + virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok); + virtual void Else(SourceLocation Loc, SourceLocation IfLoc); + virtual void Endif(SourceLocation Loc, SourceLocation IfLoc); - private: /// \brief Cached result of the last \see getPreprocessedEntitiesInRange /// query. struct { |