Skip to content

Commit

Permalink
Merge from 'main' to 'sycl-web' (105 commits)
Browse files Browse the repository at this point in the history
  CONFLICT (content): Merge conflict in clang/test/OpenMP/remarks_parallel_in_target_state_machine.c
  CONFLICT (content): Merge conflict in clang/test/OpenMP/remarks_parallel_in_multiple_target_state_machines.c
  • Loading branch information
Pavel V Chupin committed Apr 12, 2022
2 parents 19616cf + 61d418f commit 4e1bfe2
Show file tree
Hide file tree
Showing 492 changed files with 9,216 additions and 3,909 deletions.
49 changes: 41 additions & 8 deletions clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,18 +324,51 @@ void MacroToEnumCallbacks::MacroDefined(const Token &MacroNameTok,
return;

const MacroInfo *Info = MD->getMacroInfo();
if (Info->isFunctionLike() || Info->isBuiltinMacro() ||
Info->tokens().empty() || Info->tokens().size() > 2)
ArrayRef<Token> MacroTokens = Info->tokens();
if (Info->isFunctionLike() || Info->isBuiltinMacro() || MacroTokens.empty())
return;

// It can be +Lit, -Lit or just Lit.
Token Tok = Info->tokens().front();
if (Info->tokens().size() == 2) {
if (!Tok.isOneOf(tok::TokenKind::minus, tok::TokenKind::plus,
tok::TokenKind::tilde))
// Return Lit when +Lit, -Lit or ~Lit; otherwise return Unknown.
Token Unknown;
Unknown.setKind(tok::TokenKind::unknown);
auto GetUnopArg = [Unknown](Token First, Token Second) {
return First.isOneOf(tok::TokenKind::minus, tok::TokenKind::plus,
tok::TokenKind::tilde)
? Second
: Unknown;
};

// It could just be a single token.
Token Tok = MacroTokens.front();

// It can be any arbitrary nesting of matched parentheses around
// +Lit, -Lit, ~Lit or Lit.
if (MacroTokens.size() > 2) {
// Strip off matching '(', ..., ')' token pairs.
size_t Begin = 0;
size_t End = MacroTokens.size() - 1;
assert(End >= 2U);
for (; Begin < MacroTokens.size() / 2; ++Begin, --End) {
if (!MacroTokens[Begin].is(tok::TokenKind::l_paren) ||
!MacroTokens[End].is(tok::TokenKind::r_paren))
break;
}
size_t Size = End >= Begin ? (End - Begin + 1U) : 0U;

// It was a single token inside matching parens.
if (Size == 1)
Tok = MacroTokens[Begin];
else if (Size == 2)
// It can be +Lit, -Lit or ~Lit.
Tok = GetUnopArg(MacroTokens[Begin], MacroTokens[End]);
else
// Zero or too many tokens after we stripped matching parens.
return;
Tok = Info->tokens().back();
} else if (MacroTokens.size() == 2) {
// It can be +Lit, -Lit, or ~Lit.
Tok = GetUnopArg(MacroTokens.front(), MacroTokens.back());
}

if (!Tok.isLiteral() || isStringLiteral(Tok.getKind()) ||
!isIntegralConstant(Tok))
return;
Expand Down
189 changes: 92 additions & 97 deletions clang-tools-extra/clangd/index/SymbolCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Index/IndexSymbol.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Syntax/Tokens.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
Expand Down Expand Up @@ -171,6 +174,22 @@ const Decl *getRefContainer(const Decl *Enclosing,
return Enclosing;
}

// Check if there is an exact spelling of \p ND at \p Loc.
bool isSpelled(SourceLocation Loc, const NamedDecl &ND) {
auto Name = ND.getDeclName();
const auto NameKind = Name.getNameKind();
if (NameKind != DeclarationName::Identifier &&
NameKind != DeclarationName::CXXConstructorName)
return false;
const auto &AST = ND.getASTContext();
const auto &SM = AST.getSourceManager();
const auto &LO = AST.getLangOpts();
clang::Token Tok;
if (clang::Lexer::getRawToken(Loc, Tok, SM, LO))
return false;
auto StrName = Name.getAsString();
return clang::Lexer::getSpelling(Tok, SM, LO) == StrName;
}
} // namespace

// Encapsulates decisions about how to record header paths in the index,
Expand Down Expand Up @@ -545,17 +564,17 @@ bool SymbolCollector::handleDeclOccurrence(
if (!ND)
return true;

auto ID = getSymbolIDCached(ND);
if (!ID)
return true;

// Mark D as referenced if this is a reference coming from the main file.
// D may not be an interesting symbol, but it's cheaper to check at the end.
auto &SM = ASTCtx->getSourceManager();
if (Opts.CountReferences &&
(Roles & static_cast<unsigned>(index::SymbolRole::Reference)) &&
SM.getFileID(SM.getSpellingLoc(Loc)) == SM.getMainFileID())
ReferencedDecls.insert(ND);

auto ID = getSymbolID(ND);
if (!ID)
return true;
ReferencedSymbols.insert(ID);

// ND is the canonical (i.e. first) declaration. If it's in the main file
// (which is not a header), then no public declaration was visible, so assume
Expand All @@ -576,27 +595,25 @@ bool SymbolCollector::handleDeclOccurrence(
processRelations(*ND, ID, Relations);

bool CollectRef = static_cast<bool>(Opts.RefFilter & toRefKind(Roles));
bool IsOnlyRef =
!(Roles & (static_cast<unsigned>(index::SymbolRole::Declaration) |
static_cast<unsigned>(index::SymbolRole::Definition)));

if (IsOnlyRef && !CollectRef)
return true;

// Unlike other fields, e.g. Symbols (which use spelling locations), we use
// file locations for references (as it aligns the behavior of clangd's
// AST-based xref).
// FIXME: we should try to use the file locations for other fields.
if (CollectRef &&
(!IsMainFileOnly || Opts.CollectMainFileRefs ||
ND->isExternallyVisible()) &&
!isa<NamespaceDecl>(ND) &&
(Opts.RefsInHeaders ||
SM.getFileID(SM.getFileLoc(Loc)) == SM.getMainFileID()))
DeclRefs[ND].push_back(SymbolRef{SM.getFileLoc(Loc), Roles,
getRefContainer(ASTNode.Parent, Opts)});
!isa<NamespaceDecl>(ND)) {
auto FileLoc = SM.getFileLoc(Loc);
auto FID = SM.getFileID(FileLoc);
if (Opts.RefsInHeaders || FID == SM.getMainFileID()) {
addRef(ID, SymbolRef{FileLoc, FID, Roles,
getRefContainer(ASTNode.Parent, Opts),
isSpelled(FileLoc, *ND)});
}
}
// Don't continue indexing if this is a mere reference.
if (IsOnlyRef)
if (!(Roles & (static_cast<unsigned>(index::SymbolRole::Declaration) |
static_cast<unsigned>(index::SymbolRole::Definition))))
return true;

// FIXME: ObjCPropertyDecl are not properly indexed here:
Expand Down Expand Up @@ -682,7 +699,7 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name,
Name->getName() == "__GCC_HAVE_DWARF2_CFI_ASM")
return true;

auto ID = getSymbolID(Name->getName(), MI, SM);
auto ID = getSymbolIDCached(Name->getName(), MI, SM);
if (!ID)
return true;

Expand All @@ -693,9 +710,13 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name,
ASTCtx->getLangOpts());
// Do not store references to main-file macros.
if ((static_cast<unsigned>(Opts.RefFilter) & Roles) && !IsMainFileOnly &&
(Opts.RefsInHeaders || SM.getFileID(SpellingLoc) == SM.getMainFileID()))
(Opts.RefsInHeaders || SM.getFileID(SpellingLoc) == SM.getMainFileID())) {
// FIXME: Populate container information for macro references.
MacroRefs[ID].push_back({Loc, Roles, /*Container=*/nullptr});
// FIXME: All MacroRefs are marked as Spelled now, but this should be
// checked.
addRef(ID, SymbolRef{Loc, SM.getFileID(Loc), Roles, /*Container=*/nullptr,
/*Spelled=*/true});
}

// Collect symbols.
if (!Opts.CollectMacro)
Expand All @@ -711,7 +732,7 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name,
if (Opts.CountReferences &&
(Roles & static_cast<unsigned>(index::SymbolRole::Reference)) &&
SM.getFileID(SpellingLoc) == SM.getMainFileID())
ReferencedMacros.insert(Name);
ReferencedSymbols.insert(ID);

// Don't continue indexing if this is a mere reference.
// FIXME: remove macro with ID if it is undefined.
Expand Down Expand Up @@ -761,7 +782,7 @@ void SymbolCollector::processRelations(
continue;
const Decl *Object = R.RelatedSymbol;

auto ObjectID = getSymbolID(Object);
auto ObjectID = getSymbolIDCached(Object);
if (!ObjectID)
continue;

Expand Down Expand Up @@ -792,33 +813,25 @@ void SymbolCollector::setIncludeLocation(const Symbol &S, SourceLocation Loc) {

void SymbolCollector::finish() {
// At the end of the TU, add 1 to the refcount of all referenced symbols.
auto IncRef = [this](const SymbolID &ID) {
for (const auto &ID : ReferencedSymbols) {
if (const auto *S = Symbols.find(ID)) {
Symbol Inc = *S;
++Inc.References;
Symbols.insert(Inc);
}
};
for (const NamedDecl *ND : ReferencedDecls) {
if (auto ID = getSymbolID(ND)) {
IncRef(ID);
// SymbolSlab::Builder returns const symbols because strings are interned
// and modifying returned symbols without inserting again wouldn't go
// well. const_cast is safe here as we're modifying a data owned by the
// Symbol. This reduces time spent in SymbolCollector by ~1%.
++const_cast<Symbol *>(S)->References;
}
}
if (Opts.CollectMacro) {
assert(PP);
// First, drop header guards. We can't identify these until EOF.
for (const IdentifierInfo *II : IndexedMacros) {
if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo())
if (auto ID = getSymbolID(II->getName(), MI, PP->getSourceManager()))
if (auto ID =
getSymbolIDCached(II->getName(), MI, PP->getSourceManager()))
if (MI->isUsedForHeaderGuard())
Symbols.erase(ID);
}
// Now increment refcounts.
for (const IdentifierInfo *II : ReferencedMacros) {
if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo())
if (auto ID = getSymbolID(II->getName(), MI, PP->getSourceManager()))
IncRef(ID);
}
}
// Fill in IncludeHeaders.
// We delay this until end of TU so header guards are all resolved.
Expand Down Expand Up @@ -852,58 +865,7 @@ void SymbolCollector::finish() {
}
}

const auto &SM = ASTCtx->getSourceManager();
auto CollectRef = [&](SymbolID ID, const SymbolRef &LocAndRole,
bool Spelled = false) {
auto FileID = SM.getFileID(LocAndRole.Loc);
// FIXME: use the result to filter out references.
shouldIndexFile(FileID);
if (const auto *FE = SM.getFileEntryForID(FileID)) {
auto Range = getTokenRange(LocAndRole.Loc, SM, ASTCtx->getLangOpts());
Ref R;
R.Location.Start = Range.first;
R.Location.End = Range.second;
R.Location.FileURI = HeaderFileURIs->toURI(FE).c_str();
R.Kind = toRefKind(LocAndRole.Roles, Spelled);
R.Container = getSymbolID(LocAndRole.Container);
Refs.insert(ID, R);
}
};
// Populate Refs slab from MacroRefs.
// FIXME: All MacroRefs are marked as Spelled now, but this should be checked.
for (const auto &IDAndRefs : MacroRefs)
for (const auto &LocAndRole : IDAndRefs.second)
CollectRef(IDAndRefs.first, LocAndRole, /*Spelled=*/true);
// Populate Refs slab from DeclRefs.
llvm::DenseMap<FileID, std::vector<syntax::Token>> FilesToTokensCache;
for (auto &DeclAndRef : DeclRefs) {
if (auto ID = getSymbolID(DeclAndRef.first)) {
for (auto &LocAndRole : DeclAndRef.second) {
const auto FileID = SM.getFileID(LocAndRole.Loc);
// FIXME: It's better to use TokenBuffer by passing spelled tokens from
// the caller of SymbolCollector.
if (!FilesToTokensCache.count(FileID))
FilesToTokensCache[FileID] =
syntax::tokenize(FileID, SM, ASTCtx->getLangOpts());
llvm::ArrayRef<syntax::Token> Tokens = FilesToTokensCache[FileID];
// Check if the referenced symbol is spelled exactly the same way the
// corresponding NamedDecl is. If it is, mark this reference as spelled.
const auto *IdentifierToken =
spelledIdentifierTouching(LocAndRole.Loc, Tokens);
DeclarationName Name = DeclAndRef.first->getDeclName();
const auto NameKind = Name.getNameKind();
bool IsTargetKind = NameKind == DeclarationName::Identifier ||
NameKind == DeclarationName::CXXConstructorName;
bool Spelled = IdentifierToken && IsTargetKind &&
Name.getAsString() == IdentifierToken->text(SM);
CollectRef(ID, LocAndRole, Spelled);
}
}
}

ReferencedDecls.clear();
ReferencedMacros.clear();
DeclRefs.clear();
ReferencedSymbols.clear();
IncludeFiles.clear();
}

Expand Down Expand Up @@ -983,16 +945,18 @@ void SymbolCollector::addDefinition(const NamedDecl &ND,
const Symbol &DeclSym) {
if (DeclSym.Definition)
return;
const auto &SM = ND.getASTContext().getSourceManager();
auto Loc = nameLocation(ND, SM);
shouldIndexFile(SM.getFileID(Loc));
auto DefLoc = getTokenLocation(Loc);
// If we saw some forward declaration, we end up copying the symbol.
// This is not ideal, but avoids duplicating the "is this a definition" check
// in clang::index. We should only see one definition.
if (!DefLoc)
return;
Symbol S = DeclSym;
const auto &SM = ND.getASTContext().getSourceManager();
auto Loc = nameLocation(ND, SM);
// FIXME: use the result to filter out symbols.
shouldIndexFile(SM.getFileID(Loc));
if (auto DefLoc = getTokenLocation(Loc))
S.Definition = *DefLoc;
S.Definition = *DefLoc;
Symbols.insert(S);
}

Expand All @@ -1005,5 +969,36 @@ bool SymbolCollector::shouldIndexFile(FileID FID) {
return I.first->second;
}

void SymbolCollector::addRef(SymbolID ID, const SymbolRef &SR) {
const auto &SM = ASTCtx->getSourceManager();
// FIXME: use the result to filter out references.
shouldIndexFile(SR.FID);
if (const auto *FE = SM.getFileEntryForID(SR.FID)) {
auto Range = getTokenRange(SR.Loc, SM, ASTCtx->getLangOpts());
Ref R;
R.Location.Start = Range.first;
R.Location.End = Range.second;
R.Location.FileURI = HeaderFileURIs->toURI(FE).c_str();
R.Kind = toRefKind(SR.Roles, SR.Spelled);
R.Container = getSymbolIDCached(SR.Container);
Refs.insert(ID, R);
}
}

SymbolID SymbolCollector::getSymbolIDCached(const Decl *D) {
auto It = DeclToIDCache.try_emplace(D, SymbolID{});
if (It.second)
It.first->second = getSymbolID(D);
return It.first->second;
}

SymbolID SymbolCollector::getSymbolIDCached(const llvm::StringRef MacroName,
const MacroInfo *MI,
const SourceManager &SM) {
auto It = MacroToIDCache.try_emplace(MI, SymbolID{});
if (It.second)
It.first->second = getSymbolID(MacroName, MI, SM);
return It.first->second;
}
} // namespace clangd
} // namespace clang
Loading

0 comments on commit 4e1bfe2

Please sign in to comment.