137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//
337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//
537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//
837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//
1037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//  This file defines the PPConditionalDirectiveRecord class, which maintains
1137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//  a record of conditional directive regions.
1237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//
1337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
1537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
1637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
1737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis#include "clang/Basic/SourceLocation.h"
1830a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Lex/PPCallbacks.h"
1937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis#include "llvm/ADT/SmallVector.h"
2037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis#include <vector>
2137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
2237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidisnamespace clang {
2337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
2437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis/// \brief Records preprocessor conditional directive regions and allows
2537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis/// querying in which region source locations belong to.
2637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidisclass PPConditionalDirectiveRecord : public PPCallbacks {
2737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  SourceManager &SourceMgr;
2837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
2937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  SmallVector<SourceLocation, 6> CondDirectiveStack;
3037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
3137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  class CondDirectiveLoc {
3237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    SourceLocation Loc;
3337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    SourceLocation RegionLoc;
3437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
3537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  public:
3637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
3737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      : Loc(Loc), RegionLoc(RegionLoc) {}
3837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
3937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    SourceLocation getLoc() const { return Loc; }
4037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    SourceLocation getRegionLoc() const { return RegionLoc; }
4137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
4237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    class Comp {
4337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      SourceManager &SM;
4437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    public:
4537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      explicit Comp(SourceManager &SM) : SM(SM) {}
4637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      bool operator()(const CondDirectiveLoc &LHS,
4737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis                      const CondDirectiveLoc &RHS) {
4837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis        return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
4937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      }
5037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
5137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis        return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
5237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      }
5337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
5437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis        return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
5537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis      }
5637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    };
5737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  };
5837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
5937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
6037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// \brief The locations of conditional directives in source order.
6137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  CondDirectiveLocsTy CondDirectiveLocs;
6237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
6337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
6437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
6537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidispublic:
6637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// \brief Construct a new preprocessing record.
6737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  explicit PPConditionalDirectiveRecord(SourceManager &SM);
6837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
6937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  size_t getTotalMemory() const;
7037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
7137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  SourceManager &getSourceManager() const { return SourceMgr; }
7237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
7337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// \brief Returns true if the given range intersects with a conditional
7437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// directive. if a \#if/\#endif block is fully contained within the range,
7537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// this function will return false.
7637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  bool rangeIntersectsConditionalDirective(SourceRange Range) const;
7737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
7837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// \brief Returns true if the given locations are in different regions,
7937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  /// separated by conditional directive blocks.
8037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
8137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis                                                SourceLocation RHS) const {
8237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    return findConditionalDirectiveRegionLoc(LHS) !=
8337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis        findConditionalDirectiveRegionLoc(RHS);
8437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  }
8537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
8637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
8737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
8837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidisprivate:
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void If(SourceLocation Loc, SourceRange ConditionRange,
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          ConditionValueKind ConditionValue) override;
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Elif(SourceLocation Loc, SourceRange ConditionRange,
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             const MacroDirective *MD) override;
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              const MacroDirective *MD) override;
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Else(SourceLocation Loc, SourceLocation IfLoc) override;
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
9937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis};
10037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
10137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis} // end namespace clang
10237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis
10337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
104