forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			120 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| //  This file implements the PPConditionalDirectiveRecord class, which maintains
 | |
| //  a record of conditional directive regions.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| #include "clang/Lex/PPConditionalDirectiveRecord.h"
 | |
| #include "llvm/Support/Capacity.h"
 | |
| 
 | |
| using namespace clang;
 | |
| 
 | |
| PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
 | |
|   : SourceMgr(SM) {
 | |
|   CondDirectiveStack.push_back(SourceLocation());
 | |
| }
 | |
| 
 | |
| bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
 | |
|                                                       SourceRange Range) const {
 | |
|   if (Range.isInvalid())
 | |
|     return false;
 | |
| 
 | |
|   CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
 | |
|       CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
 | |
|   if (low == CondDirectiveLocs.end())
 | |
|     return false;
 | |
| 
 | |
|   if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
 | |
|     return false;
 | |
| 
 | |
|   CondDirectiveLocsTy::const_iterator
 | |
|     upp = std::upper_bound(low, CondDirectiveLocs.end(),
 | |
|                            Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
 | |
|   SourceLocation uppRegion;
 | |
|   if (upp != CondDirectiveLocs.end())
 | |
|     uppRegion = upp->getRegionLoc();
 | |
| 
 | |
|   return low->getRegionLoc() != uppRegion;
 | |
| }
 | |
| 
 | |
| SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
 | |
|                                                      SourceLocation Loc) const {
 | |
|   if (Loc.isInvalid())
 | |
|     return SourceLocation();
 | |
|   if (CondDirectiveLocs.empty())
 | |
|     return SourceLocation();
 | |
| 
 | |
|   if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
 | |
|                                           Loc))
 | |
|     return CondDirectiveStack.back();
 | |
| 
 | |
|   CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
 | |
|       CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));
 | |
|   assert(low != CondDirectiveLocs.end());
 | |
|   return low->getRegionLoc();
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::addCondDirectiveLoc(
 | |
|                                                       CondDirectiveLoc DirLoc) {
 | |
|   // Ignore directives in system headers.
 | |
|   if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
 | |
|     return;
 | |
| 
 | |
|   assert(CondDirectiveLocs.empty() ||
 | |
|          SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
 | |
|                                              DirLoc.getLoc()));
 | |
|   CondDirectiveLocs.push_back(DirLoc);
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::If(SourceLocation Loc,
 | |
|                                       SourceRange ConditionRange,
 | |
|                                       ConditionValueKind ConditionValue) {
 | |
|   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
 | |
|   CondDirectiveStack.push_back(Loc);
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
 | |
|                                          const Token &MacroNameTok,
 | |
|                                          const MacroDefinition &MD) {
 | |
|   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
 | |
|   CondDirectiveStack.push_back(Loc);
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
 | |
|                                           const Token &MacroNameTok,
 | |
|                                           const MacroDefinition &MD) {
 | |
|   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
 | |
|   CondDirectiveStack.push_back(Loc);
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
 | |
|                                         SourceRange ConditionRange,
 | |
|                                         ConditionValueKind ConditionValue,
 | |
|                                         SourceLocation IfLoc) {
 | |
|   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
 | |
|   CondDirectiveStack.back() = Loc;
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
 | |
|                                         SourceLocation IfLoc) {
 | |
|   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
 | |
|   CondDirectiveStack.back() = Loc;
 | |
| }
 | |
| 
 | |
| void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
 | |
|                                          SourceLocation IfLoc) {
 | |
|   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
 | |
|   assert(!CondDirectiveStack.empty());
 | |
|   CondDirectiveStack.pop_back();
 | |
| }
 | |
| 
 | |
| size_t PPConditionalDirectiveRecord::getTotalMemory() const {
 | |
|   return llvm::capacity_in_bytes(CondDirectiveLocs);
 | |
| }
 |