yurai007 created this revision. yurai007 added reviewers: xbolva00, nikic, serge-sans-paille, aeubanks, jansvoboda11, ymandel, cor3ntin. yurai007 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This change can be seen as code cleanup but motivation is more performance related. While browsing perf reports captured during Linux build we can notice unusual portion of instructions executed in std::vector<std::string> copy constructor like: 0.59% 0.58% clang-14 clang-14 [.] std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector or even: 1.42% 0.26% clang clang-14 [.] clang::LangOptions::LangOptions | --1.16%--clang::LangOptions::LangOptions | --0.74%--std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector After more digging we can see that relevant LangOptions std::vector members (*Files, ModuleFeatures and NoBuiltinFuncs) are constructed when Lexer::LangOpts field is initialized on list: Lexer::Lexer(..., const LangOptions &langOpts, ...) : ..., LangOpts(langOpts), Since LangOptions copy constructor is called by Lexer(..., const LangOptions &LangOpts,...) and local Lexer objects are created thousands times (in Lexer::getRawToken, Preprocessor::EnterSourceFile and more) during single module processing in frontend it makes std::vector copy constructors surprisingly hot. Unfortunately even though in current Lexer implementation mentioned std::vector members are unused and most of time empty, no compiler is smart enough to optimize their std::vector copy constructors out (take a look at test assembly): https://godbolt.org/z/hdoxPfMYY even with LTO enabled. However there is simple way to fix this. Since Lexer doesn't access *Files, ModuleFeatures, NoBuiltinFuncs and any other LangOptions fields (but only LangOptionsBase) we can simply get rid of redundant copy constructor assembly by changing LangOpts type to more appropriate LangOptionsBase class https://godbolt.org/z/bj9sodxdo After this change I can see more then 1% speedup in some of my microbenchmarks when using Clang release binary built with LTO. For Linux build gains are not so significant but still nice at the level of -0.4%/-0.5% instructions drop. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D120334 Files: clang/include/clang/Lex/Lexer.h clang/include/clang/Lex/LiteralSupport.h clang/lib/Lex/Lexer.cpp clang/lib/Lex/LiteralSupport.cpp
Index: clang/lib/Lex/LiteralSupport.cpp =================================================================== --- clang/lib/Lex/LiteralSupport.cpp +++ clang/lib/Lex/LiteralSupport.cpp @@ -994,7 +994,7 @@ /// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved /// suffixes as ud-suffixes, because the diagnostic experience is better if we /// treat it as an invalid suffix. -bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, +bool NumericLiteralParser::isValidUDSuffix(const LangOptionsBase &LangOpts, StringRef Suffix) { if (!LangOpts.CPlusPlus11 || Suffix.empty()) return false; @@ -2113,7 +2113,7 @@ /// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved /// suffixes as ud-suffixes, because the diagnostic experience is better if we /// treat it as an invalid suffix. -bool StringLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, +bool StringLiteralParser::isValidUDSuffix(const LangOptionsBase &LangOpts, StringRef Suffix) { return NumericLiteralParser::isValidUDSuffix(LangOpts, Suffix) || Suffix == "sv"; Index: clang/lib/Lex/Lexer.cpp =================================================================== --- clang/lib/Lex/Lexer.cpp +++ clang/lib/Lex/Lexer.cpp @@ -146,7 +146,7 @@ /// Lexer constructor - Create a new raw lexer object. This object is only /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the text /// range will outlive it, so it doesn't take ownership of it. -Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts, +Lexer::Lexer(SourceLocation fileloc, const LangOptionsBase &langOpts, const char *BufStart, const char *BufPtr, const char *BufEnd, bool IsFirstIncludeOfFile) : FileLoc(fileloc), LangOpts(langOpts), @@ -275,7 +275,7 @@ /// Slow case of getSpelling. Extract the characters comprising the /// spelling of this token from the provided input buffer. static size_t getSpellingSlow(const Token &Tok, const char *BufPtr, - const LangOptions &LangOpts, char *Spelling) { + const LangOptionsBase &LangOpts, char *Spelling) { assert(Tok.needsCleaning() && "getSpellingSlow called on simple token"); size_t Length = 0; @@ -328,11 +328,9 @@ /// after trigraph expansion and escaped-newline folding. In particular, this /// wants to get the true, uncanonicalized, spelling of things like digraphs /// UCNs, etc. -StringRef Lexer::getSpelling(SourceLocation loc, - SmallVectorImpl<char> &buffer, +StringRef Lexer::getSpelling(SourceLocation loc, SmallVectorImpl<char> &buffer, const SourceManager &SM, - const LangOptions &options, - bool *invalid) { + const LangOptionsBase &options, bool *invalid) { // Break down the source location. std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc); @@ -370,7 +368,7 @@ /// wants to get the true, uncanonicalized, spelling of things like digraphs /// UCNs, etc. std::string Lexer::getSpelling(const Token &Tok, const SourceManager &SourceMgr, - const LangOptions &LangOpts, bool *Invalid) { + const LangOptionsBase &LangOpts, bool *Invalid) { assert((int)Tok.getLength() >= 0 && "Token character range is bogus!"); bool CharDataInvalid = false; @@ -403,7 +401,7 @@ /// if an internal buffer is returned. unsigned Lexer::getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, - const LangOptions &LangOpts, bool *Invalid) { + const LangOptionsBase &LangOpts, bool *Invalid) { assert((int)Tok.getLength() >= 0 && "Token character range is bogus!"); const char *TokStart = nullptr; @@ -448,9 +446,8 @@ /// its length in bytes in the input file. If the token needs cleaning (e.g. /// includes a trigraph or an escaped newline) then this count includes bytes /// that are part of that. -unsigned Lexer::MeasureTokenLength(SourceLocation Loc, - const SourceManager &SM, - const LangOptions &LangOpts) { +unsigned Lexer::MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, + const LangOptionsBase &LangOpts) { Token TheTok; if (getRawToken(Loc, TheTok, SM, LangOpts)) return 0; @@ -461,7 +458,7 @@ /// \returns true if there was a failure, false on success. bool Lexer::getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, bool IgnoreWhiteSpace) { // TODO: this could be special cased for common tokens like identifiers, ')', // etc to make this faster, if it mattered. Just look at StrData[0] to handle @@ -512,7 +509,7 @@ static SourceLocation getBeginningOfFileToken(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { assert(Loc.isFileID()); std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); if (LocInfo.first.isInvalid()) @@ -560,7 +557,7 @@ SourceLocation Lexer::GetBeginningOfToken(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { if (Loc.isFileID()) return getBeginningOfFileToken(Loc, SM, LangOpts); @@ -587,7 +584,7 @@ } // namespace PreambleBounds Lexer::ComputePreamble(StringRef Buffer, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, unsigned MaxLines) { // Create a lexer starting at the beginning of the file. Note that we use a // "fake" file source location at offset 1 so that the lexer will track our @@ -726,7 +723,7 @@ unsigned Lexer::getTokenPrefixLength(SourceLocation TokStart, unsigned CharNo, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { // Figure out how many physical characters away the specified expansion // character is. This needs to take into consideration newlines and // trigraphs. @@ -786,7 +783,7 @@ /// a source location pointing to the last character in the token, etc. SourceLocation Lexer::getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { if (Loc.isInvalid()) return {}; @@ -808,7 +805,7 @@ /// token of the macro expansion. bool Lexer::isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, SourceLocation *MacroBegin) { assert(loc.isValid() && loc.isMacroID() && "Expected a valid macro loc"); @@ -828,9 +825,8 @@ /// Returns true if the given MacroID location points at the last /// token of the macro expansion. -bool Lexer::isAtEndOfMacroExpansion(SourceLocation loc, - const SourceManager &SM, - const LangOptions &LangOpts, +bool Lexer::isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, + const LangOptionsBase &LangOpts, SourceLocation *MacroEnd) { assert(loc.isValid() && loc.isMacroID() && "Expected a valid macro loc"); @@ -856,7 +852,7 @@ static CharSourceRange makeRangeFromFileLocs(CharSourceRange Range, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { SourceLocation Begin = Range.getBegin(); SourceLocation End = Range.getEnd(); assert(Begin.isFileID() && End.isFileID()); @@ -891,7 +887,7 @@ CharSourceRange Lexer::makeFileCharRange(CharSourceRange Range, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { SourceLocation Begin = Range.getBegin(); SourceLocation End = Range.getEnd(); if (Begin.isInvalid() || End.isInvalid()) @@ -958,10 +954,8 @@ return {}; } -StringRef Lexer::getSourceText(CharSourceRange Range, - const SourceManager &SM, - const LangOptions &LangOpts, - bool *Invalid) { +StringRef Lexer::getSourceText(CharSourceRange Range, const SourceManager &SM, + const LangOptionsBase &LangOpts, bool *Invalid) { Range = makeFileCharRange(Range, SM, LangOpts); if (Range.isInvalid()) { if (Invalid) *Invalid = true; @@ -996,7 +990,7 @@ StringRef Lexer::getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { assert(Loc.isMacroID() && "Only reasonable to call this on macros"); // Find the location of the immediate macro expansion. @@ -1041,8 +1035,10 @@ return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); } -StringRef Lexer::getImmediateMacroNameForDiagnostics( - SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) { +StringRef +Lexer::getImmediateMacroNameForDiagnostics(SourceLocation Loc, + const SourceManager &SM, + const LangOptionsBase &LangOpts) { assert(Loc.isMacroID() && "Only reasonable to call this on macros"); // Walk past macro argument expansions. while (SM.isMacroArgExpansion(Loc)) @@ -1066,7 +1062,8 @@ return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); } -bool Lexer::isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts) { +bool Lexer::isAsciiIdentifierContinueChar(char c, + const LangOptionsBase &LangOpts) { return isAsciiIdentifierContinue(c, LangOpts.DollarIdents); } @@ -1258,7 +1255,7 @@ Optional<Token> Lexer::findNextToken(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { if (Loc.isMacroID()) { if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc)) return None; @@ -1291,7 +1288,7 @@ /// location is inside a macro, the returned source location will be invalid. SourceLocation Lexer::findLocationAfterToken( SourceLocation Loc, tok::TokenKind TKind, const SourceManager &SM, - const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine) { + const LangOptionsBase &LangOpts, bool SkipTrailingWhitespaceAndNewLine) { Optional<Token> Tok = findNextToken(Loc, SM, LangOpts); if (!Tok || Tok->isNot(TKind)) return {}; @@ -1394,7 +1391,7 @@ /// NOTE: When this method is updated, getCharAndSizeSlow (above) should /// be updated to match. char Lexer::getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { // If we have a slash, look for an escaped newline. if (Ptr[0] == '\\') { ++Size; @@ -1456,7 +1453,7 @@ return UnicodeWhitespaceChars.contains(Codepoint); } -static bool isAllowedIDChar(uint32_t C, const LangOptions &LangOpts) { +static bool isAllowedIDChar(uint32_t C, const LangOptionsBase &LangOpts) { if (LangOpts.AsmPreprocessor) { return false; } else if (LangOpts.DollarIdents && '$' == C) { @@ -1481,7 +1478,8 @@ } } -static bool isAllowedInitiallyIDChar(uint32_t C, const LangOptions &LangOpts) { +static bool isAllowedInitiallyIDChar(uint32_t C, + const LangOptionsBase &LangOpts) { if (LangOpts.AsmPreprocessor) { return false; } @@ -1618,8 +1616,8 @@ } static void diagnoseInvalidUnicodeCodepointInIdentifier( - DiagnosticsEngine &Diags, const LangOptions &LangOpts, uint32_t CodePoint, - CharSourceRange Range, bool IsFirst) { + DiagnosticsEngine &Diags, const LangOptionsBase &LangOpts, + uint32_t CodePoint, CharSourceRange Range, bool IsFirst) { if (isASCII(CodePoint)) return; @@ -1842,7 +1840,7 @@ /// isHexaLiteral - Return true if Start points to a hex constant. /// in microsoft mode (where this is supposed to be several different tokens). -bool Lexer::isHexaLiteral(const char *Start, const LangOptions &LangOpts) { +bool Lexer::isHexaLiteral(const char *Start, const LangOptionsBase &LangOpts) { unsigned Size; char C1 = Lexer::getCharAndSizeNoWarn(Start, Size, LangOpts); if (C1 != '0') Index: clang/include/clang/Lex/LiteralSupport.h =================================================================== --- clang/include/clang/Lex/LiteralSupport.h +++ clang/include/clang/Lex/LiteralSupport.h @@ -32,6 +32,7 @@ class TargetInfo; class SourceManager; class LangOptions; +class LangOptionsBase; /// Copy characters from Input to Buf, expanding any UCNs. void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input); @@ -97,7 +98,8 @@ return SuffixBegin - ThisTokBegin; } - static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix); + static bool isValidUDSuffix(const LangOptionsBase &LangOpts, + StringRef Suffix); unsigned getRadix() const { return radix; } @@ -275,7 +277,8 @@ return UDSuffixOffset; } - static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix); + static bool isValidUDSuffix(const LangOptionsBase &LangOpts, + StringRef Suffix); private: void init(ArrayRef<Token> StringToks); Index: clang/include/clang/Lex/Lexer.h =================================================================== --- clang/include/clang/Lex/Lexer.h +++ clang/include/clang/Lex/Lexer.h @@ -91,7 +91,7 @@ SourceLocation FileLoc; // LangOpts enabled by this language (cache). - LangOptions LangOpts; + LangOptionsBase LangOpts; // True if lexer for _Pragma handling. bool Is_PragmaLexer; @@ -151,7 +151,7 @@ /// Lexer constructor - Create a new raw lexer object. This object is only /// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the /// text range will outlive it, so it doesn't take ownership of it. - Lexer(SourceLocation FileLoc, const LangOptions &LangOpts, + Lexer(SourceLocation FileLoc, const LangOptionsBase &LangOpts, const char *BufStart, const char *BufPtr, const char *BufEnd, bool IsFirstIncludeOfFile = true); @@ -175,7 +175,7 @@ /// getLangOpts - Return the language features currently enabled. /// NOTE: this lexer modifies features as a file is parsed! - const LangOptions &getLangOpts() const { return LangOpts; } + const LangOptionsBase &getLangOpts() const { return LangOpts; } /// getFileLoc - Return the File Location for the file we are lexing out of. /// The physical location encodes the location where the characters come from, @@ -311,7 +311,7 @@ /// if an internal buffer is returned. static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, bool *Invalid = nullptr); /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a @@ -321,7 +321,7 @@ /// UCNs, etc. static std::string getSpelling(const Token &Tok, const SourceManager &SourceMgr, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, bool *Invalid = nullptr); /// getSpelling - This method is used to get the spelling of the @@ -335,7 +335,7 @@ static StringRef getSpelling(SourceLocation loc, SmallVectorImpl<char> &buffer, const SourceManager &SM, - const LangOptions &options, + const LangOptionsBase &options, bool *invalid = nullptr); /// MeasureTokenLength - Relex the token at the specified location and return @@ -344,13 +344,13 @@ /// that are part of that. static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Relex the token at the specified location. /// \returns true if there was a failure, false on success. static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, bool IgnoreWhiteSpace = false); /// Given a location any where in a source buffer, find the location @@ -358,22 +358,21 @@ /// source location lands. static SourceLocation GetBeginningOfToken(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Get the physical length (including trigraphs and escaped newlines) of the /// first \p Characters characters of the token starting at TokStart. - static unsigned getTokenPrefixLength(SourceLocation TokStart, - unsigned CharNo, + static unsigned getTokenPrefixLength(SourceLocation TokStart, unsigned CharNo, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// AdvanceToTokenCharacter - If the current SourceLocation specifies a /// location at the start of a token, return a new location that specifies a /// character within the token. This handles trigraphs and escaped newlines. - static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, - unsigned Characters, - const SourceManager &SM, - const LangOptions &LangOpts) { + static SourceLocation + AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Characters, + const SourceManager &SM, + const LangOptionsBase &LangOpts) { return TokStart.getLocWithOffset( getTokenPrefixLength(TokStart, Characters, SM, LangOpts)); } @@ -395,7 +394,7 @@ /// a source location pointing to the last character in the token, etc. static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Given a token range, produce a corresponding CharSourceRange that /// is not a token range. This allows the source range to be used by @@ -403,7 +402,7 @@ /// end of the range for themselves. static CharSourceRange getAsCharRange(SourceRange Range, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts); return End.isInvalid() ? CharSourceRange() : CharSourceRange::getCharRange( @@ -411,7 +410,7 @@ } static CharSourceRange getAsCharRange(CharSourceRange Range, const SourceManager &SM, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { return Range.isTokenRange() ? getAsCharRange(Range.getAsRange(), SM, LangOpts) : Range; @@ -424,7 +423,7 @@ /// begin location of the macro. static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, SourceLocation *MacroBegin = nullptr); /// Returns true if the given MacroID location points at the last @@ -434,7 +433,7 @@ /// end location of the macro. static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, SourceLocation *MacroEnd = nullptr); /// Accepts a range and returns a character range with file locations. @@ -465,12 +464,11 @@ /// "FM(a b M)" since the range includes all of the macro expansion. static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Returns a string for the source that the range encompasses. - static StringRef getSourceText(CharSourceRange Range, - const SourceManager &SM, - const LangOptions &LangOpts, + static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, + const LangOptionsBase &LangOpts, bool *Invalid = nullptr); /// Retrieve the name of the immediate macro expansion. @@ -482,7 +480,7 @@ /// name is spelled. Thus, the result shouldn't out-live that SourceManager. static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Retrieve the name of the immediate macro expansion. /// @@ -501,8 +499,10 @@ /// \endcode /// for location of 'foo' token, this function will return "MAC1" while /// Lexer::getImmediateMacroName will return "MAC2". - static StringRef getImmediateMacroNameForDiagnostics( - SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts); + static StringRef + getImmediateMacroNameForDiagnostics(SourceLocation Loc, + const SourceManager &SM, + const LangOptionsBase &LangOpts); /// Compute the preamble of the given file. /// @@ -520,7 +520,7 @@ /// of the file begins along with a boolean value indicating whether /// the preamble ends at the beginning of a new line. static PreambleBounds ComputePreamble(StringRef Buffer, - const LangOptions &LangOpts, + const LangOptionsBase &LangOpts, unsigned MaxLines = 0); /// Finds the token that comes right after the given location. @@ -528,22 +528,20 @@ /// Returns the next token, or none if the location is inside a macro. static Optional<Token> findNextToken(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Checks that the given token is the first token that occurs after /// the given location (this excludes comments and whitespace). Returns the /// location immediately after the specified token. If the token is not found /// or the location is inside a macro, the returned source location will be /// invalid. - static SourceLocation findLocationAfterToken(SourceLocation loc, - tok::TokenKind TKind, - const SourceManager &SM, - const LangOptions &LangOpts, - bool SkipTrailingWhitespaceAndNewLine); + static SourceLocation findLocationAfterToken( + SourceLocation loc, tok::TokenKind TKind, const SourceManager &SM, + const LangOptionsBase &LangOpts, bool SkipTrailingWhitespaceAndNewLine); /// Returns true if the given character could appear in an identifier. static bool isAsciiIdentifierContinueChar(char c, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); /// Checks whether new line pointed by Str is preceded by escape /// sequence. @@ -552,7 +550,7 @@ /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever /// emit a warning. static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size, - const LangOptions &LangOpts) { + const LangOptionsBase &LangOpts) { // If this is not a trigraph and not a UCN or escaped newline, return // quickly. if (isObviouslySimpleCharacter(Ptr[0])) { @@ -695,7 +693,7 @@ /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a /// diagnostic. static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size, - const LangOptions &LangOpts); + const LangOptionsBase &LangOpts); //===--------------------------------------------------------------------===// // Other lexer functions. @@ -738,7 +736,7 @@ bool isCodeCompletionPoint(const char *CurPtr) const; void cutOffLexing() { BufferPtr = BufferEnd; } - bool isHexaLiteral(const char *Start, const LangOptions &LangOpts); + bool isHexaLiteral(const char *Start, const LangOptionsBase &LangOpts); void codeCompleteIncludedFile(const char *PathStart, const char *CompletionPoint, bool IsAngled);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits