1249261Sdim//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim// 10249261Sdim// This file implements the PPConditionalDirectiveRecord class, which maintains 11249261Sdim// a record of conditional directive regions. 12249261Sdim// 13249261Sdim//===----------------------------------------------------------------------===// 14249261Sdim#include "clang/Lex/PPConditionalDirectiveRecord.h" 15249261Sdim#include "llvm/Support/Capacity.h" 16249261Sdim 17249261Sdimusing namespace clang; 18249261Sdim 19249261SdimPPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM) 20249261Sdim : SourceMgr(SM) { 21249261Sdim CondDirectiveStack.push_back(SourceLocation()); 22249261Sdim} 23249261Sdim 24249261Sdimbool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective( 25249261Sdim SourceRange Range) const { 26249261Sdim if (Range.isInvalid()) 27249261Sdim return false; 28249261Sdim 29249261Sdim CondDirectiveLocsTy::const_iterator 30249261Sdim low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), 31249261Sdim Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr)); 32249261Sdim if (low == CondDirectiveLocs.end()) 33249261Sdim return false; 34249261Sdim 35249261Sdim if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc())) 36249261Sdim return false; 37249261Sdim 38249261Sdim CondDirectiveLocsTy::const_iterator 39249261Sdim upp = std::upper_bound(low, CondDirectiveLocs.end(), 40249261Sdim Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr)); 41249261Sdim SourceLocation uppRegion; 42249261Sdim if (upp != CondDirectiveLocs.end()) 43249261Sdim uppRegion = upp->getRegionLoc(); 44249261Sdim 45249261Sdim return low->getRegionLoc() != uppRegion; 46249261Sdim} 47249261Sdim 48249261SdimSourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc( 49249261Sdim SourceLocation Loc) const { 50249261Sdim if (Loc.isInvalid()) 51249261Sdim return SourceLocation(); 52249261Sdim if (CondDirectiveLocs.empty()) 53249261Sdim return SourceLocation(); 54249261Sdim 55249261Sdim if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), 56249261Sdim Loc)) 57249261Sdim return CondDirectiveStack.back(); 58249261Sdim 59249261Sdim CondDirectiveLocsTy::const_iterator 60249261Sdim low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), 61249261Sdim Loc, CondDirectiveLoc::Comp(SourceMgr)); 62249261Sdim assert(low != CondDirectiveLocs.end()); 63249261Sdim return low->getRegionLoc(); 64249261Sdim} 65249261Sdim 66249261Sdimvoid PPConditionalDirectiveRecord::addCondDirectiveLoc( 67249261Sdim CondDirectiveLoc DirLoc) { 68249261Sdim // Ignore directives in system headers. 69249261Sdim if (SourceMgr.isInSystemHeader(DirLoc.getLoc())) 70249261Sdim return; 71249261Sdim 72249261Sdim assert(CondDirectiveLocs.empty() || 73249261Sdim SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), 74249261Sdim DirLoc.getLoc())); 75249261Sdim CondDirectiveLocs.push_back(DirLoc); 76249261Sdim} 77249261Sdim 78249261Sdimvoid PPConditionalDirectiveRecord::If(SourceLocation Loc, 79263509Sdim SourceRange ConditionRange, 80263509Sdim bool ConditionValue) { 81249261Sdim addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 82249261Sdim CondDirectiveStack.push_back(Loc); 83249261Sdim} 84249261Sdim 85249261Sdimvoid PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc, 86249261Sdim const Token &MacroNameTok, 87249261Sdim const MacroDirective *MD) { 88249261Sdim addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 89249261Sdim CondDirectiveStack.push_back(Loc); 90249261Sdim} 91249261Sdim 92249261Sdimvoid PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc, 93249261Sdim const Token &MacroNameTok, 94249261Sdim const MacroDirective *MD) { 95249261Sdim addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 96249261Sdim CondDirectiveStack.push_back(Loc); 97249261Sdim} 98249261Sdim 99249261Sdimvoid PPConditionalDirectiveRecord::Elif(SourceLocation Loc, 100249261Sdim SourceRange ConditionRange, 101263509Sdim bool ConditionValue, 102249261Sdim SourceLocation IfLoc) { 103249261Sdim addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 104249261Sdim CondDirectiveStack.back() = Loc; 105249261Sdim} 106249261Sdim 107249261Sdimvoid PPConditionalDirectiveRecord::Else(SourceLocation Loc, 108249261Sdim SourceLocation IfLoc) { 109249261Sdim addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 110249261Sdim CondDirectiveStack.back() = Loc; 111249261Sdim} 112249261Sdim 113249261Sdimvoid PPConditionalDirectiveRecord::Endif(SourceLocation Loc, 114249261Sdim SourceLocation IfLoc) { 115249261Sdim addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 116249261Sdim assert(!CondDirectiveStack.empty()); 117249261Sdim CondDirectiveStack.pop_back(); 118249261Sdim} 119249261Sdim 120249261Sdimsize_t PPConditionalDirectiveRecord::getTotalMemory() const { 121249261Sdim return llvm::capacity_in_bytes(CondDirectiveLocs); 122249261Sdim} 123