142 lines · cpp
1//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the PPConditionalDirectiveRecord class, which maintains10// a record of conditional directive regions.11//12//===----------------------------------------------------------------------===//13#include "clang/Lex/PPConditionalDirectiveRecord.h"14#include "llvm/Support/Capacity.h"15 16using namespace clang;17 18PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)19 : SourceMgr(SM) {20 CondDirectiveStack.push_back(SourceLocation());21}22 23bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(24 SourceRange Range) const {25 if (Range.isInvalid())26 return false;27 28 CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(29 CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));30 if (low == CondDirectiveLocs.end())31 return false;32 33 if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))34 return false;35 36 CondDirectiveLocsTy::const_iterator37 upp = std::upper_bound(low, CondDirectiveLocs.end(),38 Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));39 SourceLocation uppRegion;40 if (upp != CondDirectiveLocs.end())41 uppRegion = upp->getRegionLoc();42 43 return low->getRegionLoc() != uppRegion;44}45 46SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(47 SourceLocation Loc) const {48 if (Loc.isInvalid())49 return SourceLocation();50 if (CondDirectiveLocs.empty())51 return SourceLocation();52 53 if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),54 Loc))55 return CondDirectiveStack.back();56 57 CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(58 CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));59 assert(low != CondDirectiveLocs.end());60 return low->getRegionLoc();61}62 63void PPConditionalDirectiveRecord::addCondDirectiveLoc(64 CondDirectiveLoc DirLoc) {65 // Ignore directives in system headers.66 if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))67 return;68 69 assert(CondDirectiveLocs.empty() ||70 SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),71 DirLoc.getLoc()));72 CondDirectiveLocs.push_back(DirLoc);73}74 75void PPConditionalDirectiveRecord::If(SourceLocation Loc,76 SourceRange ConditionRange,77 ConditionValueKind ConditionValue) {78 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));79 CondDirectiveStack.push_back(Loc);80}81 82void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,83 const Token &MacroNameTok,84 const MacroDefinition &MD) {85 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));86 CondDirectiveStack.push_back(Loc);87}88 89void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,90 const Token &MacroNameTok,91 const MacroDefinition &MD) {92 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));93 CondDirectiveStack.push_back(Loc);94}95 96void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,97 SourceRange ConditionRange,98 ConditionValueKind ConditionValue,99 SourceLocation IfLoc) {100 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));101 CondDirectiveStack.back() = Loc;102}103 104void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, const Token &,105 const MacroDefinition &) {106 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));107 CondDirectiveStack.back() = Loc;108}109void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,110 SourceLocation) {111 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));112 CondDirectiveStack.back() = Loc;113}114 115void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,116 const MacroDefinition &) {117 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));118 CondDirectiveStack.back() = Loc;119}120void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,121 SourceLocation) {122 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));123 CondDirectiveStack.back() = Loc;124}125 126void PPConditionalDirectiveRecord::Else(SourceLocation Loc,127 SourceLocation IfLoc) {128 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));129 CondDirectiveStack.back() = Loc;130}131 132void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,133 SourceLocation IfLoc) {134 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));135 assert(!CondDirectiveStack.empty());136 CondDirectiveStack.pop_back();137}138 139size_t PPConditionalDirectiveRecord::getTotalMemory() const {140 return llvm::capacity_in_bytes(CondDirectiveLocs);141}142