clang API Documentation
00001 //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the PPConditionalDirectiveRecord class, which maintains 00011 // a record of conditional directive regions. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #include "clang/Lex/PPConditionalDirectiveRecord.h" 00015 #include "llvm/Support/Capacity.h" 00016 00017 using namespace clang; 00018 00019 PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM) 00020 : SourceMgr(SM) { 00021 CondDirectiveStack.push_back(SourceLocation()); 00022 } 00023 00024 bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective( 00025 SourceRange Range) const { 00026 if (Range.isInvalid()) 00027 return false; 00028 00029 CondDirectiveLocsTy::const_iterator 00030 low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), 00031 Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr)); 00032 if (low == CondDirectiveLocs.end()) 00033 return false; 00034 00035 if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc())) 00036 return false; 00037 00038 CondDirectiveLocsTy::const_iterator 00039 upp = std::upper_bound(low, CondDirectiveLocs.end(), 00040 Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr)); 00041 SourceLocation uppRegion; 00042 if (upp != CondDirectiveLocs.end()) 00043 uppRegion = upp->getRegionLoc(); 00044 00045 return low->getRegionLoc() != uppRegion; 00046 } 00047 00048 SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc( 00049 SourceLocation Loc) const { 00050 if (Loc.isInvalid()) 00051 return SourceLocation(); 00052 if (CondDirectiveLocs.empty()) 00053 return SourceLocation(); 00054 00055 if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), 00056 Loc)) 00057 return CondDirectiveStack.back(); 00058 00059 CondDirectiveLocsTy::const_iterator 00060 low = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(), 00061 Loc, CondDirectiveLoc::Comp(SourceMgr)); 00062 assert(low != CondDirectiveLocs.end()); 00063 return low->getRegionLoc(); 00064 } 00065 00066 void PPConditionalDirectiveRecord::addCondDirectiveLoc( 00067 CondDirectiveLoc DirLoc) { 00068 // Ignore directives in system headers. 00069 if (SourceMgr.isInSystemHeader(DirLoc.getLoc())) 00070 return; 00071 00072 assert(CondDirectiveLocs.empty() || 00073 SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(), 00074 DirLoc.getLoc())); 00075 CondDirectiveLocs.push_back(DirLoc); 00076 } 00077 00078 void PPConditionalDirectiveRecord::If(SourceLocation Loc, 00079 SourceRange ConditionRange, 00080 ConditionValueKind ConditionValue) { 00081 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 00082 CondDirectiveStack.push_back(Loc); 00083 } 00084 00085 void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc, 00086 const Token &MacroNameTok, 00087 const MacroDirective *MD) { 00088 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 00089 CondDirectiveStack.push_back(Loc); 00090 } 00091 00092 void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc, 00093 const Token &MacroNameTok, 00094 const MacroDirective *MD) { 00095 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 00096 CondDirectiveStack.push_back(Loc); 00097 } 00098 00099 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc, 00100 SourceRange ConditionRange, 00101 ConditionValueKind ConditionValue, 00102 SourceLocation IfLoc) { 00103 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 00104 CondDirectiveStack.back() = Loc; 00105 } 00106 00107 void PPConditionalDirectiveRecord::Else(SourceLocation Loc, 00108 SourceLocation IfLoc) { 00109 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 00110 CondDirectiveStack.back() = Loc; 00111 } 00112 00113 void PPConditionalDirectiveRecord::Endif(SourceLocation Loc, 00114 SourceLocation IfLoc) { 00115 addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back())); 00116 assert(!CondDirectiveStack.empty()); 00117 CondDirectiveStack.pop_back(); 00118 } 00119 00120 size_t PPConditionalDirectiveRecord::getTotalMemory() const { 00121 return llvm::capacity_in_bytes(CondDirectiveLocs); 00122 }