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