diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-08-22 19:00:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-13 20:39:49 +0000 |
commit | fe6060f10f634930ff71b7c50291ddc610da2475 (patch) | |
tree | 1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/clang/lib/Index | |
parent | b61bce17f346d79cecfd8f195a64b10f77be43b1 (diff) | |
parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/Index')
9 files changed, 216 insertions, 54 deletions
diff --git a/contrib/llvm-project/clang/lib/Index/FileIndexRecord.cpp b/contrib/llvm-project/clang/lib/Index/FileIndexRecord.cpp index df18a9aed8b7..d392a2bedeba 100644 --- a/contrib/llvm-project/clang/lib/Index/FileIndexRecord.cpp +++ b/contrib/llvm-project/clang/lib/Index/FileIndexRecord.cpp @@ -17,42 +17,63 @@ using namespace clang; using namespace clang::index; +ArrayRef<DeclOccurrence> +FileIndexRecord::getDeclOccurrencesSortedByOffset() const { + if (!IsSorted) { + llvm::stable_sort(Decls, + [](const DeclOccurrence &A, const DeclOccurrence &B) { + return A.Offset < B.Offset; + }); + IsSorted = true; + } + return Decls; +} + void FileIndexRecord::addDeclOccurence(SymbolRoleSet Roles, unsigned Offset, const Decl *D, ArrayRef<SymbolRelation> Relations) { assert(D->isCanonicalDecl() && "Occurrences should be associated with their canonical decl"); + IsSorted = false; + Decls.emplace_back(Roles, Offset, D, Relations); +} - auto IsNextOccurence = [&]() -> bool { - if (Decls.empty()) - return true; - auto &Last = Decls.back(); - return Last.Offset < Offset; - }; - - if (IsNextOccurence()) { - Decls.emplace_back(Roles, Offset, D, Relations); - return; - } +void FileIndexRecord::addMacroOccurence(SymbolRoleSet Roles, unsigned Offset, + const IdentifierInfo *Name, + const MacroInfo *MI) { + IsSorted = false; + Decls.emplace_back(Roles, Offset, Name, MI); +} - DeclOccurrence NewInfo(Roles, Offset, D, Relations); - // We keep Decls in order as we need to access them in this order in all cases. - auto It = llvm::upper_bound(Decls, NewInfo); - Decls.insert(It, std::move(NewInfo)); +void FileIndexRecord::removeHeaderGuardMacros() { + auto It = + std::remove_if(Decls.begin(), Decls.end(), [](const DeclOccurrence &D) { + if (const auto *MI = D.DeclOrMacro.dyn_cast<const MacroInfo *>()) + return MI->isUsedForHeaderGuard(); + return false; + }); + Decls.erase(It, Decls.end()); } -void FileIndexRecord::print(llvm::raw_ostream &OS) const { +void FileIndexRecord::print(llvm::raw_ostream &OS, SourceManager &SM) const { OS << "DECLS BEGIN ---\n"; for (auto &DclInfo : Decls) { - const Decl *D = DclInfo.Dcl; - SourceManager &SM = D->getASTContext().getSourceManager(); - SourceLocation Loc = SM.getFileLoc(D->getLocation()); - PresumedLoc PLoc = SM.getPresumedLoc(Loc); - OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' << PLoc.getLine() - << ':' << PLoc.getColumn(); - - if (auto ND = dyn_cast<NamedDecl>(D)) { - OS << ' ' << ND->getDeclName(); + if (const auto *D = DclInfo.DeclOrMacro.dyn_cast<const Decl *>()) { + SourceLocation Loc = SM.getFileLoc(D->getLocation()); + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' + << PLoc.getLine() << ':' << PLoc.getColumn(); + + if (const auto *ND = dyn_cast<NamedDecl>(D)) { + OS << ' ' << ND->getDeclName(); + } + } else { + const auto *MI = DclInfo.DeclOrMacro.get<const MacroInfo *>(); + SourceLocation Loc = SM.getFileLoc(MI->getDefinitionLoc()); + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' + << PLoc.getLine() << ':' << PLoc.getColumn(); + OS << ' ' << DclInfo.MacroName->getName(); } OS << '\n'; diff --git a/contrib/llvm-project/clang/lib/Index/FileIndexRecord.h b/contrib/llvm-project/clang/lib/Index/FileIndexRecord.h index 37bf96a71964..621d5b78977d 100644 --- a/contrib/llvm-project/clang/lib/Index/FileIndexRecord.h +++ b/contrib/llvm-project/clang/lib/Index/FileIndexRecord.h @@ -27,14 +27,13 @@ class FileIndexRecord { private: FileID FID; bool IsSystem; - std::vector<DeclOccurrence> Decls; + mutable bool IsSorted = false; + mutable std::vector<DeclOccurrence> Decls; public: FileIndexRecord(FileID FID, bool IsSystem) : FID(FID), IsSystem(IsSystem) {} - ArrayRef<DeclOccurrence> getDeclOccurrencesSortedByOffset() const { - return Decls; - } + ArrayRef<DeclOccurrence> getDeclOccurrencesSortedByOffset() const; FileID getFileID() const { return FID; } bool isSystem() const { return IsSystem; } @@ -48,7 +47,21 @@ public: /// \param Relations the set of symbols related to this occurrence. void addDeclOccurence(SymbolRoleSet Roles, unsigned Offset, const Decl *D, ArrayRef<SymbolRelation> Relations); - void print(llvm::raw_ostream &OS) const; + + /// Adds an occurrence of the given macro at the supplied \c Offset. + /// + /// \param Roles the roles the occurrence fulfills in this position. + /// \param Offset the offset in the file of this occurrence. + /// \param Name the name of the macro. + /// \param MI the canonical declaration this is an occurrence of. + void addMacroOccurence(SymbolRoleSet Roles, unsigned Offset, + const IdentifierInfo *Name, const MacroInfo *MI); + + /// Remove any macro occurrences for header guards. When preprocessing, this + /// will only be accurate after HandleEndOfFile. + void removeHeaderGuardMacros(); + + void print(llvm::raw_ostream &OS, SourceManager &SM) const; }; } // end namespace index diff --git a/contrib/llvm-project/clang/lib/Index/IndexBody.cpp b/contrib/llvm-project/clang/lib/Index/IndexBody.cpp index e4944fd0fc3b..fa35f749d028 100644 --- a/contrib/llvm-project/clang/lib/Index/IndexBody.cpp +++ b/contrib/llvm-project/clang/lib/Index/IndexBody.cpp @@ -286,9 +286,6 @@ public: } bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - if (E->isClassReceiver()) - IndexCtx.handleReference(E->getClassReceiver(), E->getReceiverLocation(), - Parent, ParentDC); if (E->isExplicitProperty()) { SmallVector<SymbolRelation, 2> Relations; SymbolRoleSet Roles = getRolesForRef(E, Relations); @@ -466,6 +463,15 @@ public: } return true; } + + bool VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { + SmallVector<SymbolRelation, 4> Relations; + SymbolRoleSet Roles = getRolesForRef(E, Relations); + for (auto *D : E->decls()) + IndexCtx.handleReference(D, E->getNameLoc(), Parent, ParentDC, Roles, + Relations, E); + return true; + } }; } // anonymous namespace diff --git a/contrib/llvm-project/clang/lib/Index/IndexDecl.cpp b/contrib/llvm-project/clang/lib/Index/IndexDecl.cpp index 2ba323e63575..00adb3644ff2 100644 --- a/contrib/llvm-project/clang/lib/Index/IndexDecl.cpp +++ b/contrib/llvm-project/clang/lib/Index/IndexDecl.cpp @@ -759,7 +759,7 @@ bool IndexingContext::indexDeclContext(const DeclContext *DC) { } bool IndexingContext::indexTopLevelDecl(const Decl *D) { - if (D->getLocation().isInvalid()) + if (!D || D->getLocation().isInvalid()) return true; if (isa<ObjCMethodDecl>(D)) diff --git a/contrib/llvm-project/clang/lib/Index/IndexSymbol.cpp b/contrib/llvm-project/clang/lib/Index/IndexSymbol.cpp index 0d2e557cdd36..68e457de5265 100644 --- a/contrib/llvm-project/clang/lib/Index/IndexSymbol.cpp +++ b/contrib/llvm-project/clang/lib/Index/IndexSymbol.cpp @@ -329,6 +329,11 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { Info.Kind = SymbolKind::Using; Info.Lang = SymbolLanguage::CXX; break; + case Decl::UsingEnum: + Info.Kind = SymbolKind::Using; + Info.Lang = SymbolLanguage::CXX; + Info.SubKind = SymbolSubKind::UsingEnum; + break; case Decl::Binding: Info.Kind = SymbolKind::Variable; Info.Lang = SymbolLanguage::CXX; @@ -542,6 +547,8 @@ StringRef index::getSymbolSubKindString(SymbolSubKind K) { case SymbolSubKind::AccessorSetter: return "acc-set"; case SymbolSubKind::UsingTypename: return "using-typename"; case SymbolSubKind::UsingValue: return "using-value"; + case SymbolSubKind::UsingEnum: + return "using-enum"; } llvm_unreachable("invalid symbol subkind"); } diff --git a/contrib/llvm-project/clang/lib/Index/IndexingAction.cpp b/contrib/llvm-project/clang/lib/Index/IndexingAction.cpp index 4986303cac47..c9fcaad31128 100644 --- a/contrib/llvm-project/clang/lib/Index/IndexingAction.cpp +++ b/contrib/llvm-project/clang/lib/Index/IndexingAction.cpp @@ -51,6 +51,51 @@ public: MacroNameTok.getLocation(), *MD.getMacroInfo()); } + + void Defined(const Token &MacroNameTok, const MacroDefinition &MD, + SourceRange Range) override { + if (!MD.getMacroInfo()) // Ignore nonexistent macro. + return; + // Note: this is defined(M), not #define M + IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(), + MacroNameTok.getLocation(), + *MD.getMacroInfo()); + } + void Ifdef(SourceLocation Loc, const Token &MacroNameTok, + const MacroDefinition &MD) override { + if (!MD.getMacroInfo()) // Ignore non-existent macro. + return; + IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(), + MacroNameTok.getLocation(), + *MD.getMacroInfo()); + } + void Ifndef(SourceLocation Loc, const Token &MacroNameTok, + const MacroDefinition &MD) override { + if (!MD.getMacroInfo()) // Ignore nonexistent macro. + return; + IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(), + MacroNameTok.getLocation(), + *MD.getMacroInfo()); + } + + using PPCallbacks::Elifdef; + using PPCallbacks::Elifndef; + void Elifdef(SourceLocation Loc, const Token &MacroNameTok, + const MacroDefinition &MD) override { + if (!MD.getMacroInfo()) // Ignore non-existent macro. + return; + IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(), + MacroNameTok.getLocation(), + *MD.getMacroInfo()); + } + void Elifndef(SourceLocation Loc, const Token &MacroNameTok, + const MacroDefinition &MD) override { + if (!MD.getMacroInfo()) // Ignore non-existent macro. + return; + IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(), + MacroNameTok.getLocation(), + *MD.getMacroInfo()); + } }; class IndexASTConsumer final : public ASTConsumer { @@ -162,23 +207,54 @@ static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) { Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor); } -static void indexPreprocessorMacros(const Preprocessor &PP, +static void indexPreprocessorMacro(const IdentifierInfo *II, + const MacroInfo *MI, + MacroDirective::Kind DirectiveKind, + SourceLocation Loc, + IndexDataConsumer &DataConsumer) { + // When using modules, it may happen that we find #undef of a macro that + // was defined in another module. In such case, MI may be nullptr, since + // we only look for macro definitions in the current TU. In that case, + // there is nothing to index. + if (!MI) + return; + + // Skip implicit visibility change. + if (DirectiveKind == MacroDirective::MD_Visibility) + return; + + auto Role = DirectiveKind == MacroDirective::MD_Define + ? SymbolRole::Definition + : SymbolRole::Undefinition; + DataConsumer.handleMacroOccurrence(II, MI, static_cast<unsigned>(Role), Loc); +} + +static void indexPreprocessorMacros(Preprocessor &PP, IndexDataConsumer &DataConsumer) { - for (const auto &M : PP.macros()) - if (MacroDirective *MD = M.second.getLatest()) { - auto *MI = MD->getMacroInfo(); - // When using modules, it may happen that we find #undef of a macro that - // was defined in another module. In such case, MI may be nullptr, since - // we only look for macro definitions in the current TU. In that case, - // there is nothing to index. - if (!MI) - continue; - - DataConsumer.handleMacroOccurrence( - M.first, MD->getMacroInfo(), - static_cast<unsigned>(index::SymbolRole::Definition), - MD->getLocation()); + for (const auto &M : PP.macros()) { + for (auto *MD = M.second.getLatest(); MD; MD = MD->getPrevious()) { + indexPreprocessorMacro(M.first, MD->getMacroInfo(), MD->getKind(), + MD->getLocation(), DataConsumer); } + } +} + +static void indexPreprocessorModuleMacros(Preprocessor &PP, + serialization::ModuleFile &Mod, + IndexDataConsumer &DataConsumer) { + for (const auto &M : PP.macros()) { + if (M.second.getLatest() == nullptr) { + for (auto *MM : PP.getLeafModuleMacros(M.first)) { + auto *OwningMod = MM->getOwningModule(); + if (OwningMod && OwningMod->getASTFile() == Mod.File) { + if (auto *MI = MM->getMacroInfo()) { + indexPreprocessorMacro(M.first, MI, MacroDirective::MD_Define, + MI->getDefinitionLoc(), DataConsumer); + } + } + } + } + } } void index::indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer, @@ -225,8 +301,9 @@ void index::indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader, IndexCtx.setASTContext(Ctx); DataConsumer.initialize(Ctx); - if (Opts.IndexMacrosInPreprocessor) - indexPreprocessorMacros(Reader.getPreprocessor(), DataConsumer); + if (Opts.IndexMacrosInPreprocessor) { + indexPreprocessorModuleMacros(Reader.getPreprocessor(), Mod, DataConsumer); + } for (const Decl *D : Reader.getModuleFileLevelDecls(Mod)) { IndexCtx.indexTopLevelDecl(D); diff --git a/contrib/llvm-project/clang/lib/Index/IndexingContext.cpp b/contrib/llvm-project/clang/lib/Index/IndexingContext.cpp index 784a6008575b..8a962a055bac 100644 --- a/contrib/llvm-project/clang/lib/Index/IndexingContext.cpp +++ b/contrib/llvm-project/clang/lib/Index/IndexingContext.cpp @@ -457,6 +457,8 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, void IndexingContext::handleMacroDefined(const IdentifierInfo &Name, SourceLocation Loc, const MacroInfo &MI) { + if (!shouldIndexMacroOccurrence(/*IsRef=*/false, Loc)) + return; SymbolRoleSet Roles = (unsigned)SymbolRole::Definition; DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc); } @@ -464,6 +466,8 @@ void IndexingContext::handleMacroDefined(const IdentifierInfo &Name, void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name, SourceLocation Loc, const MacroInfo &MI) { + if (!shouldIndexMacroOccurrence(/*IsRef=*/false, Loc)) + return; SymbolRoleSet Roles = (unsigned)SymbolRole::Undefinition; DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc); } @@ -471,6 +475,37 @@ void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name, void IndexingContext::handleMacroReference(const IdentifierInfo &Name, SourceLocation Loc, const MacroInfo &MI) { + if (!shouldIndexMacroOccurrence(/*IsRef=*/true, Loc)) + return; SymbolRoleSet Roles = (unsigned)SymbolRole::Reference; DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc); } + +bool IndexingContext::shouldIndexMacroOccurrence(bool IsRef, + SourceLocation Loc) { + if (!IndexOpts.IndexMacros) + return false; + + switch (IndexOpts.SystemSymbolFilter) { + case IndexingOptions::SystemSymbolFilterKind::None: + break; + case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly: + if (!IsRef) + return true; + break; + case IndexingOptions::SystemSymbolFilterKind::All: + return true; + } + + SourceManager &SM = Ctx->getSourceManager(); + FileID FID = SM.getFileID(SM.getFileLoc(Loc)); + if (FID.isInvalid()) + return false; + + bool Invalid = false; + const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid); + if (Invalid || !SEntry.isFile()) + return false; + + return SEntry.getFile().getFileCharacteristic() == SrcMgr::C_User; +} diff --git a/contrib/llvm-project/clang/lib/Index/IndexingContext.h b/contrib/llvm-project/clang/lib/Index/IndexingContext.h index 3136878c080c..626d81f003e9 100644 --- a/contrib/llvm-project/clang/lib/Index/IndexingContext.h +++ b/contrib/llvm-project/clang/lib/Index/IndexingContext.h @@ -124,6 +124,8 @@ public: private: bool shouldIgnoreIfImplicit(const Decl *D); + bool shouldIndexMacroOccurrence(bool IsRef, SourceLocation Loc); + bool handleDeclOccurrence(const Decl *D, SourceLocation Loc, bool IsRef, const Decl *Parent, SymbolRoleSet Roles, diff --git a/contrib/llvm-project/clang/lib/Index/USRGeneration.cpp b/contrib/llvm-project/clang/lib/Index/USRGeneration.cpp index abaeb1a4232f..6db763ca6f2b 100644 --- a/contrib/llvm-project/clang/lib/Index/USRGeneration.cpp +++ b/contrib/llvm-project/clang/lib/Index/USRGeneration.cpp @@ -732,6 +732,8 @@ void USRGenerator::VisitType(QualType T) { #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: #include "clang/Basic/PPCTypes.def" +#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: +#include "clang/Basic/RISCVVTypes.def" case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: @@ -1101,15 +1103,14 @@ bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD, bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, const SourceManager &SM, SmallVectorImpl<char> &Buf) { - // Don't generate USRs for things with invalid locations. - if (MacroName.empty() || Loc.isInvalid()) + if (MacroName.empty()) return true; llvm::raw_svector_ostream Out(Buf); // Assume that system headers are sane. Don't put source location // information into the USR if the macro comes from a system header. - bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc); + bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc); Out << getUSRSpacePrefix(); if (ShouldGenerateLocation) |