xref: /freebsd/contrib/llvm-project/clang/lib/Lex/PPConditionalDirectiveRecord.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements the PPConditionalDirectiveRecord class, which maintains
100b57cec5SDimitry Andric //  a record of conditional directive regions.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric #include "clang/Lex/PPConditionalDirectiveRecord.h"
140b57cec5SDimitry Andric #include "llvm/Support/Capacity.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric using namespace clang;
170b57cec5SDimitry Andric 
PPConditionalDirectiveRecord(SourceManager & SM)180b57cec5SDimitry Andric PPConditionalDirectiveRecord::PPConditionalDirectiveRecord(SourceManager &SM)
190b57cec5SDimitry Andric   : SourceMgr(SM) {
200b57cec5SDimitry Andric   CondDirectiveStack.push_back(SourceLocation());
210b57cec5SDimitry Andric }
220b57cec5SDimitry Andric 
rangeIntersectsConditionalDirective(SourceRange Range) const230b57cec5SDimitry Andric bool PPConditionalDirectiveRecord::rangeIntersectsConditionalDirective(
240b57cec5SDimitry Andric                                                       SourceRange Range) const {
250b57cec5SDimitry Andric   if (Range.isInvalid())
260b57cec5SDimitry Andric     return false;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric   CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
290b57cec5SDimitry Andric       CondDirectiveLocs, Range.getBegin(), CondDirectiveLoc::Comp(SourceMgr));
300b57cec5SDimitry Andric   if (low == CondDirectiveLocs.end())
310b57cec5SDimitry Andric     return false;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), low->getLoc()))
340b57cec5SDimitry Andric     return false;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric   CondDirectiveLocsTy::const_iterator
370b57cec5SDimitry Andric     upp = std::upper_bound(low, CondDirectiveLocs.end(),
380b57cec5SDimitry Andric                            Range.getEnd(), CondDirectiveLoc::Comp(SourceMgr));
390b57cec5SDimitry Andric   SourceLocation uppRegion;
400b57cec5SDimitry Andric   if (upp != CondDirectiveLocs.end())
410b57cec5SDimitry Andric     uppRegion = upp->getRegionLoc();
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   return low->getRegionLoc() != uppRegion;
440b57cec5SDimitry Andric }
450b57cec5SDimitry Andric 
findConditionalDirectiveRegionLoc(SourceLocation Loc) const460b57cec5SDimitry Andric SourceLocation PPConditionalDirectiveRecord::findConditionalDirectiveRegionLoc(
470b57cec5SDimitry Andric                                                      SourceLocation Loc) const {
480b57cec5SDimitry Andric   if (Loc.isInvalid())
490b57cec5SDimitry Andric     return SourceLocation();
500b57cec5SDimitry Andric   if (CondDirectiveLocs.empty())
510b57cec5SDimitry Andric     return SourceLocation();
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   if (SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
540b57cec5SDimitry Andric                                           Loc))
550b57cec5SDimitry Andric     return CondDirectiveStack.back();
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   CondDirectiveLocsTy::const_iterator low = llvm::lower_bound(
580b57cec5SDimitry Andric       CondDirectiveLocs, Loc, CondDirectiveLoc::Comp(SourceMgr));
590b57cec5SDimitry Andric   assert(low != CondDirectiveLocs.end());
600b57cec5SDimitry Andric   return low->getRegionLoc();
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
addCondDirectiveLoc(CondDirectiveLoc DirLoc)630b57cec5SDimitry Andric void PPConditionalDirectiveRecord::addCondDirectiveLoc(
640b57cec5SDimitry Andric                                                       CondDirectiveLoc DirLoc) {
650b57cec5SDimitry Andric   // Ignore directives in system headers.
660b57cec5SDimitry Andric   if (SourceMgr.isInSystemHeader(DirLoc.getLoc()))
670b57cec5SDimitry Andric     return;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   assert(CondDirectiveLocs.empty() ||
700b57cec5SDimitry Andric          SourceMgr.isBeforeInTranslationUnit(CondDirectiveLocs.back().getLoc(),
710b57cec5SDimitry Andric                                              DirLoc.getLoc()));
720b57cec5SDimitry Andric   CondDirectiveLocs.push_back(DirLoc);
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
If(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue)750b57cec5SDimitry Andric void PPConditionalDirectiveRecord::If(SourceLocation Loc,
760b57cec5SDimitry Andric                                       SourceRange ConditionRange,
770b57cec5SDimitry Andric                                       ConditionValueKind ConditionValue) {
780b57cec5SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
790b57cec5SDimitry Andric   CondDirectiveStack.push_back(Loc);
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)820b57cec5SDimitry Andric void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
830b57cec5SDimitry Andric                                          const Token &MacroNameTok,
840b57cec5SDimitry Andric                                          const MacroDefinition &MD) {
850b57cec5SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
860b57cec5SDimitry Andric   CondDirectiveStack.push_back(Loc);
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)890b57cec5SDimitry Andric void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
900b57cec5SDimitry Andric                                           const Token &MacroNameTok,
910b57cec5SDimitry Andric                                           const MacroDefinition &MD) {
920b57cec5SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
930b57cec5SDimitry Andric   CondDirectiveStack.push_back(Loc);
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
Elif(SourceLocation Loc,SourceRange ConditionRange,ConditionValueKind ConditionValue,SourceLocation IfLoc)960b57cec5SDimitry Andric void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
970b57cec5SDimitry Andric                                         SourceRange ConditionRange,
980b57cec5SDimitry Andric                                         ConditionValueKind ConditionValue,
990b57cec5SDimitry Andric                                         SourceLocation IfLoc) {
1000b57cec5SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
1010b57cec5SDimitry Andric   CondDirectiveStack.back() = Loc;
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
Elifdef(SourceLocation Loc,const Token &,const MacroDefinition &)104*fe6060f1SDimitry Andric void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, const Token &,
105*fe6060f1SDimitry Andric                                            const MacroDefinition &) {
106*fe6060f1SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
107*fe6060f1SDimitry Andric   CondDirectiveStack.back() = Loc;
108*fe6060f1SDimitry Andric }
Elifdef(SourceLocation Loc,SourceRange,SourceLocation)109*fe6060f1SDimitry Andric void PPConditionalDirectiveRecord::Elifdef(SourceLocation Loc, SourceRange,
110*fe6060f1SDimitry Andric                                            SourceLocation) {
111*fe6060f1SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
112*fe6060f1SDimitry Andric   CondDirectiveStack.back() = Loc;
113*fe6060f1SDimitry Andric }
114*fe6060f1SDimitry Andric 
Elifndef(SourceLocation Loc,const Token &,const MacroDefinition &)115*fe6060f1SDimitry Andric void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, const Token &,
116*fe6060f1SDimitry Andric                                             const MacroDefinition &) {
117*fe6060f1SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
118*fe6060f1SDimitry Andric   CondDirectiveStack.back() = Loc;
119*fe6060f1SDimitry Andric }
Elifndef(SourceLocation Loc,SourceRange,SourceLocation)120*fe6060f1SDimitry Andric void PPConditionalDirectiveRecord::Elifndef(SourceLocation Loc, SourceRange,
121*fe6060f1SDimitry Andric                                             SourceLocation) {
122*fe6060f1SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
123*fe6060f1SDimitry Andric   CondDirectiveStack.back() = Loc;
124*fe6060f1SDimitry Andric }
125*fe6060f1SDimitry Andric 
Else(SourceLocation Loc,SourceLocation IfLoc)1260b57cec5SDimitry Andric void PPConditionalDirectiveRecord::Else(SourceLocation Loc,
1270b57cec5SDimitry Andric                                         SourceLocation IfLoc) {
1280b57cec5SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
1290b57cec5SDimitry Andric   CondDirectiveStack.back() = Loc;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
Endif(SourceLocation Loc,SourceLocation IfLoc)1320b57cec5SDimitry Andric void PPConditionalDirectiveRecord::Endif(SourceLocation Loc,
1330b57cec5SDimitry Andric                                          SourceLocation IfLoc) {
1340b57cec5SDimitry Andric   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
1350b57cec5SDimitry Andric   assert(!CondDirectiveStack.empty());
1360b57cec5SDimitry Andric   CondDirectiveStack.pop_back();
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
getTotalMemory() const1390b57cec5SDimitry Andric size_t PPConditionalDirectiveRecord::getTotalMemory() const {
1400b57cec5SDimitry Andric   return llvm::capacity_in_bytes(CondDirectiveLocs);
1410b57cec5SDimitry Andric }
142