File indexing completed on 2026-05-10 08:36:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
0015 #define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
0016
0017 #include "clang/Basic/FileEntry.h"
0018 #include "clang/Basic/SourceLocation.h"
0019 #include "clang/Lex/MultipleIncludeOpt.h"
0020 #include "clang/Lex/Token.h"
0021 #include "llvm/ADT/ArrayRef.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include <cassert>
0024
0025 namespace clang {
0026
0027 class FileEntry;
0028 class Preprocessor;
0029
0030 class PreprocessorLexer {
0031 virtual void anchor();
0032
0033 protected:
0034 friend class Preprocessor;
0035
0036
0037 Preprocessor *PP = nullptr;
0038
0039
0040 const FileID FID;
0041
0042
0043 unsigned InitialNumSLocEntries = 0;
0044
0045
0046
0047
0048
0049
0050 bool ParsingPreprocessorDirective = false;
0051
0052
0053 bool ParsingFilename = false;
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 bool LexingRawMode = false;
0069
0070
0071
0072 MultipleIncludeOpt MIOpt;
0073
0074
0075
0076 SmallVector<PPConditionalInfo, 4> ConditionalStack;
0077
0078 PreprocessorLexer() : FID() {}
0079 PreprocessorLexer(Preprocessor *pp, FileID fid);
0080 virtual ~PreprocessorLexer() = default;
0081
0082 virtual void IndirectLex(Token& Result) = 0;
0083
0084
0085 virtual SourceLocation getSourceLocation() = 0;
0086
0087
0088
0089
0090
0091
0092
0093 void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
0094 bool FoundNonSkip, bool FoundElse) {
0095 PPConditionalInfo CI;
0096 CI.IfLoc = DirectiveStart;
0097 CI.WasSkipping = WasSkipping;
0098 CI.FoundNonSkip = FoundNonSkip;
0099 CI.FoundElse = FoundElse;
0100 ConditionalStack.push_back(CI);
0101 }
0102 void pushConditionalLevel(const PPConditionalInfo &CI) {
0103 ConditionalStack.push_back(CI);
0104 }
0105
0106
0107
0108
0109 bool popConditionalLevel(PPConditionalInfo &CI) {
0110 if (ConditionalStack.empty())
0111 return true;
0112 CI = ConditionalStack.pop_back_val();
0113 return false;
0114 }
0115
0116
0117
0118 PPConditionalInfo &peekConditionalLevel() {
0119 assert(!ConditionalStack.empty() && "No conditionals active!");
0120 return ConditionalStack.back();
0121 }
0122
0123 unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
0124
0125 public:
0126 PreprocessorLexer(const PreprocessorLexer &) = delete;
0127 PreprocessorLexer &operator=(const PreprocessorLexer &) = delete;
0128
0129
0130
0131
0132
0133 void LexIncludeFilename(Token &FilenameTok);
0134
0135
0136
0137 void setParsingPreprocessorDirective(bool f) {
0138 ParsingPreprocessorDirective = f;
0139 }
0140
0141
0142 bool isLexingRawMode() const { return LexingRawMode; }
0143
0144
0145 Preprocessor *getPP() const { return PP; }
0146
0147 FileID getFileID() const {
0148 assert(PP &&
0149 "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
0150 return FID;
0151 }
0152
0153
0154 unsigned getInitialNumSLocEntries() const {
0155 return InitialNumSLocEntries;
0156 }
0157
0158
0159
0160 OptionalFileEntryRef getFileEntry() const;
0161
0162
0163
0164 using conditional_iterator =
0165 SmallVectorImpl<PPConditionalInfo>::const_iterator;
0166
0167 conditional_iterator conditional_begin() const {
0168 return ConditionalStack.begin();
0169 }
0170
0171 conditional_iterator conditional_end() const {
0172 return ConditionalStack.end();
0173 }
0174
0175 void setConditionalLevels(ArrayRef<PPConditionalInfo> CL) {
0176 ConditionalStack.clear();
0177 ConditionalStack.append(CL.begin(), CL.end());
0178 }
0179 };
0180
0181 }
0182
0183 #endif