Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:57

0001 //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the PPConditionalDirectiveRecord class, which maintains
0010 //  a record of conditional directive regions.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 #ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
0014 #define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
0015 
0016 #include "clang/Basic/SourceLocation.h"
0017 #include "clang/Lex/PPCallbacks.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include <vector>
0020 
0021 namespace clang {
0022 
0023 /// Records preprocessor conditional directive regions and allows
0024 /// querying in which region source locations belong to.
0025 class PPConditionalDirectiveRecord : public PPCallbacks {
0026   SourceManager &SourceMgr;
0027 
0028   SmallVector<SourceLocation, 6> CondDirectiveStack;
0029 
0030   class CondDirectiveLoc {
0031     SourceLocation Loc;
0032     SourceLocation RegionLoc;
0033 
0034   public:
0035     CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
0036       : Loc(Loc), RegionLoc(RegionLoc) {}
0037 
0038     SourceLocation getLoc() const { return Loc; }
0039     SourceLocation getRegionLoc() const { return RegionLoc; }
0040 
0041     class Comp {
0042       SourceManager &SM;
0043     public:
0044       explicit Comp(SourceManager &SM) : SM(SM) {}
0045       bool operator()(const CondDirectiveLoc &LHS,
0046                       const CondDirectiveLoc &RHS) {
0047         return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
0048       }
0049       bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
0050         return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
0051       }
0052       bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
0053         return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
0054       }
0055     };
0056   };
0057 
0058   typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
0059   /// The locations of conditional directives in source order.
0060   CondDirectiveLocsTy CondDirectiveLocs;
0061 
0062   void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
0063 
0064 public:
0065   /// Construct a new preprocessing record.
0066   explicit PPConditionalDirectiveRecord(SourceManager &SM);
0067 
0068   size_t getTotalMemory() const;
0069 
0070   SourceManager &getSourceManager() const { return SourceMgr; }
0071 
0072   /// Returns true if the given range intersects with a conditional
0073   /// directive. if a \#if/\#endif block is fully contained within the range,
0074   /// this function will return false.
0075   bool rangeIntersectsConditionalDirective(SourceRange Range) const;
0076 
0077   /// Returns true if the given locations are in different regions,
0078   /// separated by conditional directive blocks.
0079   bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
0080                                                 SourceLocation RHS) const {
0081     return findConditionalDirectiveRegionLoc(LHS) !=
0082         findConditionalDirectiveRegionLoc(RHS);
0083   }
0084 
0085   SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
0086 
0087 private:
0088   void If(SourceLocation Loc, SourceRange ConditionRange,
0089           ConditionValueKind ConditionValue) override;
0090   void Elif(SourceLocation Loc, SourceRange ConditionRange,
0091             ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
0092   void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
0093              const MacroDefinition &MD) override;
0094   void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
0095               const MacroDefinition &MD) override;
0096   void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
0097                const MacroDefinition &MD) override;
0098   void Elifdef(SourceLocation Loc, SourceRange ConditionRange,
0099                SourceLocation IfLoc) override;
0100   void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
0101                 const MacroDefinition &MD) override;
0102   void Elifndef(SourceLocation Loc, SourceRange ConditionRange,
0103                 SourceLocation IfLoc) override;
0104   void Else(SourceLocation Loc, SourceLocation IfLoc) override;
0105   void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
0106 };
0107 
0108 } // end namespace clang
0109 
0110 #endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H