clang API Documentation

PPConditionalDirectiveRecord.cpp
Go to the documentation of this file.
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 }