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 17 using namespace clang; 18 19 PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM) 20 : SourceMgr(SM) { 21 CondDirectiveStack.push_back(SourceLocation()); 22 } 23 24 bool 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 48 SourceLocation 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 66 void 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 78 void PPConditionalDirectiveRecord::If(SourceLocation Loc, 79 SourceRange ConditionRange, 80 ConditionValueKind ConditionValue) { 81 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 82 CondDirectiveStack.push_back(Loc); 83 } 84 85 void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc, 86 const Token &MacroNameTok, 87 const MacroDefinition &MD) { 88 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 89 CondDirectiveStack.push_back(Loc); 90 } 91 92 void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc, 93 const Token &MacroNameTok, 94 const MacroDefinition &MD) { 95 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 96 CondDirectiveStack.push_back(Loc); 97 } 98 99 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc, 100 SourceRange ConditionRange, 101 ConditionValueKind ConditionValue, 102 SourceLocation IfLoc) { 103 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 104 CondDirectiveStack.back() = Loc; 105 } 106 107 void PPConditionalDirectiveRecord::Else(SourceLocation Loc, 108 SourceLocation IfLoc) { 109 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 110 CondDirectiveStack.back() = Loc; 111 } 112 113 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc, 114 SourceLocation IfLoc) { 115 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 116 assert(!CondDirectiveStack.empty()); 117 CondDirectiveStack.pop_back(); 118 } 119 120 size_t PPConditionalDirectiveRecord::getTotalMemory() const { 121 return llvm::capacity_in_bytes(CondDirectiveLocs); 122 } 123