2012-12-04 15:27:05 +08:00
|
|
|
//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// 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 = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
|
|
|
|
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 = std::lower_bound(CondDirectiveLocs.begin(), CondDirectiveLocs.end(),
|
|
|
|
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) {
|
|
|
|
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
|
|
|
|
CondDirectiveStack.push_back(Loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
|
2012-12-08 10:21:11 +08:00
|
|
|
const Token &MacroNameTok,
|
2013-02-24 08:05:14 +08:00
|
|
|
const MacroDirective *MD) {
|
2012-12-04 15:27:05 +08:00
|
|
|
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
|
|
|
|
CondDirectiveStack.push_back(Loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
|
2012-12-08 10:21:11 +08:00
|
|
|
const Token &MacroNameTok,
|
2013-02-24 08:05:14 +08:00
|
|
|
const MacroDirective *MD) {
|
2012-12-04 15:27:05 +08:00
|
|
|
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
|
|
|
|
CondDirectiveStack.push_back(Loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
|
|
|
|
SourceRange ConditionRange,
|
|
|
|
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);
|
|
|
|
}
|