PPConditionalDirectiveRecord.cpp revision 37ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17
1//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the PPConditionalDirectiveRecord class, which maintains 11// a record of conditional directive regions. 12// 13//===----------------------------------------------------------------------===// 14#include "clang/Lex/PPConditionalDirectiveRecord.h" 15#include "llvm/Support/Capacity.h" 16 17using namespace clang; 18 19PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM) 20 : SourceMgr(SM) { 21 CondDirectiveStack.push_back(SourceLocation()); 22} 23 24bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective( 25 SourceRange Range) const { 26 if (Range.isInvalid()) 27 return false; 28 29 CondDirectiveLocsTy::const_iterator 30 low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), 31 Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr)); 32 if (low == CondDirectiveLocs.end()) 33 return false; 34 35 if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc())) 36 return false; 37 38 CondDirectiveLocsTy::const_iterator 39 upp = std::upper_bound(low, CondDirectiveLocs.end(), 40 Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr)); 41 SourceLocation uppRegion; 42 if (upp != CondDirectiveLocs.end()) 43 uppRegion = upp->getRegionLoc(); 44 45 return low->getRegionLoc() != uppRegion; 46} 47 48SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc( 49 SourceLocation Loc) const { 50 if (Loc.isInvalid()) 51 return SourceLocation(); 52 if (CondDirectiveLocs.empty()) 53 return SourceLocation(); 54 55 if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), 56 Loc)) 57 return CondDirectiveStack.back(); 58 59 CondDirectiveLocsTy::const_iterator 60 low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), 61 Loc, CondDirectiveLoc::Comp(SourceMgr)); 62 assert(low != CondDirectiveLocs.end()); 63 return low->getRegionLoc(); 64} 65 66void PPConditionalDirectiveRecord::addCondDirectiveLoc( 67 CondDirectiveLoc DirLoc) { 68 // Ignore directives in system headers. 69 if (SourceMgr.isInSystemHeader(DirLoc.getLoc())) 70 return; 71 72 assert(CondDirectiveLocs.empty() || 73 SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), 74 DirLoc.getLoc())); 75 CondDirectiveLocs.push_back(DirLoc); 76} 77 78void PPConditionalDirectiveRecord::If(SourceLocation Loc, 79 SourceRange ConditionRange) { 80 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 81 CondDirectiveStack.push_back(Loc); 82} 83 84void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc, 85 const Token &MacroNameTok) { 86 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 87 CondDirectiveStack.push_back(Loc); 88} 89 90void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc, 91 const Token &MacroNameTok) { 92 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 93 CondDirectiveStack.push_back(Loc); 94} 95 96void PPConditionalDirectiveRecord::Elif(SourceLocation Loc, 97 SourceRange ConditionRange, 98 SourceLocation IfLoc) { 99 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 100 CondDirectiveStack.back() = Loc; 101} 102 103void PPConditionalDirectiveRecord::Else(SourceLocation Loc, 104 SourceLocation IfLoc) { 105 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 106 CondDirectiveStack.back() = Loc; 107} 108 109void PPConditionalDirectiveRecord::Endif(SourceLocation Loc, 110 SourceLocation IfLoc) { 111 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 112 assert(!CondDirectiveStack.empty()); 113 CondDirectiveStack.pop_back(); 114} 115 116size_t PPConditionalDirectiveRecord::getTotalMemory() const { 117 return llvm::capacity_in_bytes(CondDirectiveLocs); 118} 119