Skip to content

Commit

Permalink
Merge branch 'main' into thinlto
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrofin authored Jul 29, 2024
2 parents e5f9ec4 + 7b99b1d commit bb58e0f
Show file tree
Hide file tree
Showing 29 changed files with 385 additions and 179 deletions.
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ Bug Fixes to C++ Support
- Fixed a crash when an expression with a dependent ``__typeof__`` type is used as the operand of a unary operator. (#GH97646)
- Fixed a failed assertion when checking invalid delete operator declaration. (#GH96191)
- Fix a crash when checking destructor reference with an invalid initializer. (#GH97230)
- Clang now correctly parses potentially declarative nested-name-specifiers in pointer-to-member declarators.

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -250,6 +251,9 @@ Fixed Point Support in Clang
AST Matchers
------------

- Fixed an issue with the `hasName` and `hasAnyName` matcher when matching
inline namespaces with an enclosing namespace of the same name.

clang-format
------------

Expand Down
26 changes: 23 additions & 3 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,11 @@ class Preprocessor {
/// invoked (at which point the last position is popped).
std::vector<CachedTokensTy::size_type> BacktrackPositions;

/// Stack of cached tokens/initial number of cached tokens pairs, allowing
/// nested unannotated backtracks.
std::vector<std::pair<CachedTokensTy, CachedTokensTy::size_type>>
UnannotatedBacktrackTokens;

/// True if \p Preprocessor::SkipExcludedConditionalBlock() is running.
/// This is used to guard against calling this function recursively.
///
Expand Down Expand Up @@ -1722,8 +1727,16 @@ class Preprocessor {
/// at some point after EnableBacktrackAtThisPos. If you don't, caching of
/// tokens will continue indefinitely.
///
void EnableBacktrackAtThisPos();
/// \param Unannotated Whether token annotations are reverted upon calling
/// Backtrack().
void EnableBacktrackAtThisPos(bool Unannotated = false);

private:
std::pair<CachedTokensTy::size_type, bool> LastBacktrackPos();

CachedTokensTy PopUnannotatedBacktrackTokens();

public:
/// Disable the last EnableBacktrackAtThisPos call.
void CommitBacktrackedTokens();

Expand All @@ -1735,6 +1748,12 @@ class Preprocessor {
/// caching of tokens is on.
bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }

/// True if EnableBacktrackAtThisPos() was called and
/// caching of unannotated tokens is on.
bool isUnannotatedBacktrackEnabled() const {
return !UnannotatedBacktrackTokens.empty();
}

/// Lex the next token for this preprocessor.
void Lex(Token &Result);

Expand Down Expand Up @@ -1841,8 +1860,9 @@ class Preprocessor {
void RevertCachedTokens(unsigned N) {
assert(isBacktrackEnabled() &&
"Should only be called when tokens are cached for backtracking");
assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back())
&& "Should revert tokens up to the last backtrack position, not more");
assert(signed(CachedLexPos) - signed(N) >=
signed(LastBacktrackPos().first) &&
"Should revert tokens up to the last backtrack position, not more");
assert(signed(CachedLexPos) - signed(N) >= 0 &&
"Corrupted backtrack positions ?");
CachedLexPos -= N;
Expand Down
15 changes: 8 additions & 7 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,8 @@ class Parser : public CodeCompletionHandler {
/// ....
/// TPA.Revert();
///
/// If the Unannotated parameter is true, any token annotations created
/// during the tentative parse are reverted.
class TentativeParsingAction {
Parser &P;
PreferredTypeBuilder PrevPreferredType;
Expand All @@ -1034,15 +1036,15 @@ class Parser : public CodeCompletionHandler {
bool isActive;

public:
explicit TentativeParsingAction(Parser &p)
explicit TentativeParsingAction(Parser &p, bool Unannotated = false)
: P(p), PrevPreferredType(P.PreferredType) {
PrevTok = P.Tok;
PrevTentativelyDeclaredIdentifierCount =
P.TentativelyDeclaredIdentifiers.size();
PrevParenCount = P.ParenCount;
PrevBracketCount = P.BracketCount;
PrevBraceCount = P.BraceCount;
P.PP.EnableBacktrackAtThisPos();
P.PP.EnableBacktrackAtThisPos(Unannotated);
isActive = true;
}
void Commit() {
Expand Down Expand Up @@ -1073,13 +1075,11 @@ class Parser : public CodeCompletionHandler {
class RevertingTentativeParsingAction
: private Parser::TentativeParsingAction {
public:
RevertingTentativeParsingAction(Parser &P)
: Parser::TentativeParsingAction(P) {}
using TentativeParsingAction::TentativeParsingAction;

~RevertingTentativeParsingAction() { Revert(); }
};

class UnannotatedTentativeParsingAction;

/// ObjCDeclContextSwitch - An object used to switch context from
/// an objective-c decl context to its enclosing decl context and
/// back.
Expand Down Expand Up @@ -1984,7 +1984,8 @@ class Parser : public CodeCompletionHandler {
CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHasErrors,
bool EnteringContext, bool *MayBePseudoDestructor = nullptr,
bool IsTypename = false, const IdentifierInfo **LastII = nullptr,
bool OnlyNamespace = false, bool InUsingDeclaration = false);
bool OnlyNamespace = false, bool InUsingDeclaration = false,
bool Disambiguation = false);

//===--------------------------------------------------------------------===//
// C++11 5.1.2: Lambda expressions
Expand Down
23 changes: 16 additions & 7 deletions clang/lib/ASTMatchers/ASTMatchersInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,14 +537,23 @@ class PatternSet {
/// that didn't match.
/// Return true if there are still any patterns left.
bool consumeNameSuffix(StringRef NodeName, bool CanSkip) {
for (size_t I = 0; I < Patterns.size();) {
if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P,
NodeName) ||
CanSkip) {
++I;
} else {
Patterns.erase(Patterns.begin() + I);
if (CanSkip) {
// If we can skip the node, then we need to handle the case where a
// skipped node has the same name as its parent.
// namespace a { inline namespace a { class A; } }
// cxxRecordDecl(hasName("::a::A"))
// To do this, any patterns that match should be duplicated in our set,
// one of them with the tail removed.
for (size_t I = 0, E = Patterns.size(); I != E; ++I) {
StringRef Pattern = Patterns[I].P;
if (ast_matchers::internal::consumeNameSuffix(Patterns[I].P, NodeName))
Patterns.push_back({Pattern, Patterns[I].IsFullyQualified});
}
} else {
llvm::erase_if(Patterns, [&NodeName](auto &Pattern) {
return !::clang::ast_matchers::internal::consumeNameSuffix(Pattern.P,
NodeName);
});
}
return !Patterns.empty();
}
Expand Down
48 changes: 40 additions & 8 deletions clang/lib/Lex/PPCaching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
#include "clang/Lex/Preprocessor.h"
using namespace clang;

std::pair<Preprocessor::CachedTokensTy::size_type, bool>
Preprocessor::LastBacktrackPos() {
assert(isBacktrackEnabled());
auto BacktrackPos = BacktrackPositions.back();
bool Unannotated =
static_cast<CachedTokensTy::difference_type>(BacktrackPos) < 0;
return {Unannotated ? ~BacktrackPos : BacktrackPos, Unannotated};
}

// EnableBacktrackAtThisPos - From the point that this method is called, and
// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
// keeps track of the lexed tokens so that a subsequent Backtrack() call will
Expand All @@ -22,26 +31,45 @@ using namespace clang;
// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
// be combined with the EnableBacktrackAtThisPos calls in reverse order.
void Preprocessor::EnableBacktrackAtThisPos() {
void Preprocessor::EnableBacktrackAtThisPos(bool Unannotated) {
assert(LexLevel == 0 && "cannot use lookahead while lexing");
BacktrackPositions.push_back(CachedLexPos);
BacktrackPositions.push_back(Unannotated ? ~CachedLexPos : CachedLexPos);
if (Unannotated)
UnannotatedBacktrackTokens.emplace_back(CachedTokens, CachedTokens.size());
EnterCachingLexMode();
}

Preprocessor::CachedTokensTy Preprocessor::PopUnannotatedBacktrackTokens() {
assert(isUnannotatedBacktrackEnabled() && "missing unannotated tokens?");
auto [UnannotatedTokens, NumCachedToks] =
std::move(UnannotatedBacktrackTokens.back());
UnannotatedBacktrackTokens.pop_back();
// If another unannotated backtrack is active, propagate any tokens that were
// lexed (not cached) since EnableBacktrackAtThisPos was last called.
if (isUnannotatedBacktrackEnabled())
UnannotatedBacktrackTokens.back().first.append(
UnannotatedTokens.begin() + NumCachedToks, UnannotatedTokens.end());
return std::move(UnannotatedTokens);
}

// Disable the last EnableBacktrackAtThisPos call.
void Preprocessor::CommitBacktrackedTokens() {
assert(!BacktrackPositions.empty()
&& "EnableBacktrackAtThisPos was not called!");
assert(isBacktrackEnabled() && "EnableBacktrackAtThisPos was not called!");
auto [BacktrackPos, Unannotated] = LastBacktrackPos();
BacktrackPositions.pop_back();
if (Unannotated)
PopUnannotatedBacktrackTokens();
}

// Make Preprocessor re-lex the tokens that were lexed since
// EnableBacktrackAtThisPos() was previously called.
void Preprocessor::Backtrack() {
assert(!BacktrackPositions.empty()
&& "EnableBacktrackAtThisPos was not called!");
CachedLexPos = BacktrackPositions.back();
assert(isBacktrackEnabled() && "EnableBacktrackAtThisPos was not called!");
auto [BacktrackPos, Unannotated] = LastBacktrackPos();
BacktrackPositions.pop_back();
CachedLexPos = BacktrackPos;
if (Unannotated)
CachedTokens = PopUnannotatedBacktrackTokens();
recomputeCurLexerKind();
}

Expand All @@ -67,6 +95,8 @@ void Preprocessor::CachingLex(Token &Result) {
EnterCachingLexModeUnchecked();
CachedTokens.push_back(Result);
++CachedLexPos;
if (isUnannotatedBacktrackEnabled())
UnannotatedBacktrackTokens.back().first.push_back(Result);
return;
}

Expand Down Expand Up @@ -108,6 +138,8 @@ const Token &Preprocessor::PeekAhead(unsigned N) {
for (size_t C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
CachedTokens.push_back(Token());
Lex(CachedTokens.back());
if (isUnannotatedBacktrackEnabled())
UnannotatedBacktrackTokens.back().first.push_back(CachedTokens.back());
}
EnterCachingLexMode();
return CachedTokens.back();
Expand All @@ -124,7 +156,7 @@ void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) {
CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1;
if (AnnotBegin->getLocation() == Tok.getLocation()) {
assert((BacktrackPositions.empty() || BacktrackPositions.back() <= i) &&
assert((!isBacktrackEnabled() || LastBacktrackPos().first <= i) &&
"The backtrack pos points inside the annotated tokens!");
// Replace the cached tokens with the single annotation token.
if (i < CachedLexPos)
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Lex/Preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
}

Preprocessor::~Preprocessor() {
assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
assert(!isBacktrackEnabled() && "EnableBacktrack/Backtrack imbalance!");

IncludeMacroStack.clear();

Expand Down
41 changes: 2 additions & 39 deletions clang/lib/Parse/ParseCXXInlineMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,41 +1205,6 @@ bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {
return true;
}

/// A tentative parsing action that can also revert token annotations.
class Parser::UnannotatedTentativeParsingAction : public TentativeParsingAction {
public:
explicit UnannotatedTentativeParsingAction(Parser &Self,
tok::TokenKind EndKind)
: TentativeParsingAction(Self), Self(Self), EndKind(EndKind) {
// Stash away the old token stream, so we can restore it once the
// tentative parse is complete.
TentativeParsingAction Inner(Self);
Self.ConsumeAndStoreUntil(EndKind, Toks, true, /*ConsumeFinalToken*/false);
Inner.Revert();
}

void RevertAnnotations() {
Revert();

// Put back the original tokens.
Self.SkipUntil(EndKind, StopAtSemi | StopBeforeMatch);
if (Toks.size()) {
auto Buffer = std::make_unique<Token[]>(Toks.size());
std::copy(Toks.begin() + 1, Toks.end(), Buffer.get());
Buffer[Toks.size() - 1] = Self.Tok;
Self.PP.EnterTokenStream(std::move(Buffer), Toks.size(), true,
/*IsReinject*/ true);

Self.Tok = Toks.front();
}
}

private:
Parser &Self;
CachedTokens Toks;
tok::TokenKind EndKind;
};

/// ConsumeAndStoreInitializer - Consume and store the token at the passed token
/// container until the end of the current initializer expression (either a
/// default argument or an in-class initializer for a non-static data member).
Expand Down Expand Up @@ -1277,9 +1242,7 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
// syntactically-valid init-declarator-list, then this comma ends
// the default initializer.
{
UnannotatedTentativeParsingAction PA(*this,
CIK == CIK_DefaultInitializer
? tok::semi : tok::r_paren);
TentativeParsingAction TPA(*this, /*Unannotated=*/true);
Sema::TentativeAnalysisScope Scope(Actions);

TPResult Result = TPResult::Error;
Expand Down Expand Up @@ -1307,7 +1270,7 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
// Put the token stream back and undo any annotations we performed
// after the comma. They may reflect a different parse than the one
// we will actually perform at the end of the class.
PA.RevertAnnotations();
TPA.Revert();

// If what follows could be a declaration, it is a declaration.
if (Result != TPResult::False && Result != TPResult::Error)
Expand Down
Loading

0 comments on commit bb58e0f

Please sign in to comment.