Skip to content

Commit 06ee794

Browse files
committed
Merge commit '93c87fc06eca' from llvm.org/main into apple/main
2 parents 2daf798 + 93c87fc commit 06ee794

File tree

15 files changed

+285
-55
lines changed

15 files changed

+285
-55
lines changed

clang/include/clang/Index/DeclOccurrence.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,31 @@
99
#ifndef LLVM_CLANG_INDEX_DECLOCCURRENCE_H
1010
#define LLVM_CLANG_INDEX_DECLOCCURRENCE_H
1111

12+
#include "clang/AST/DeclBase.h"
1213
#include "clang/Basic/LLVM.h"
1314
#include "clang/Index/IndexSymbol.h"
15+
#include "clang/Lex/MacroInfo.h"
1416
#include "llvm/ADT/ArrayRef.h"
17+
#include "llvm/ADT/PointerUnion.h"
1518
#include "llvm/ADT/SmallVector.h"
1619

1720
namespace clang {
18-
class Decl;
19-
2021
namespace index {
2122

2223
struct DeclOccurrence {
2324
SymbolRoleSet Roles;
2425
unsigned Offset;
25-
const Decl *Dcl;
26+
llvm::PointerUnion<const Decl *, const MacroInfo *> DeclOrMacro;
27+
const IdentifierInfo *MacroName = nullptr;
2628
SmallVector<SymbolRelation, 3> Relations;
2729

2830
DeclOccurrence(SymbolRoleSet R, unsigned Offset, const Decl *D,
2931
ArrayRef<SymbolRelation> Relations)
30-
: Roles(R), Offset(Offset), Dcl(D),
32+
: Roles(R), Offset(Offset), DeclOrMacro(D),
3133
Relations(Relations.begin(), Relations.end()) {}
34+
DeclOccurrence(SymbolRoleSet R, unsigned Offset, const IdentifierInfo *Name,
35+
const MacroInfo *MI)
36+
: Roles(R), Offset(Offset), DeclOrMacro(MI), MacroName(Name) {}
3237

3338
friend bool operator<(const DeclOccurrence &LHS, const DeclOccurrence &RHS) {
3439
return LHS.Offset < RHS.Offset;

clang/include/clang/Index/IndexingOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct IndexingOptions {
2828
SystemSymbolFilterKind::DeclarationsOnly;
2929
bool IndexFunctionLocals = false;
3030
bool IndexImplicitInstantiation = false;
31+
bool IndexMacros = true;
3132
// Whether to index macro definitions in the Preprocesor when preprocessor
3233
// callback is not available (e.g. after parsing has finished). Note that
3334
// macro references are not available in Proprocessor.

clang/lib/Index/FileIndexRecord.cpp

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,68 @@
1717
using namespace clang;
1818
using namespace clang::index;
1919

20-
void FileIndexRecord::addDeclOccurence(SymbolRoleSet Roles, unsigned Offset,
21-
const Decl *D,
22-
ArrayRef<SymbolRelation> Relations) {
23-
assert(D->isCanonicalDecl() &&
24-
"Occurrences should be associated with their canonical decl");
25-
20+
static void addOccurrence(std::vector<DeclOccurrence> &Decls,
21+
DeclOccurrence Info) {
2622
auto IsNextOccurence = [&]() -> bool {
2723
if (Decls.empty())
2824
return true;
2925
auto &Last = Decls.back();
30-
return Last.Offset < Offset;
26+
return Last.Offset < Info.Offset;
3127
};
3228

3329
if (IsNextOccurence()) {
34-
Decls.emplace_back(Roles, Offset, D, Relations);
30+
Decls.push_back(std::move(Info));
3531
return;
3632
}
3733

38-
DeclOccurrence NewInfo(Roles, Offset, D, Relations);
3934
// We keep Decls in order as we need to access them in this order in all cases.
40-
auto It = llvm::upper_bound(Decls, NewInfo);
41-
Decls.insert(It, std::move(NewInfo));
35+
auto It = llvm::upper_bound(Decls, Info);
36+
Decls.insert(It, std::move(Info));
37+
}
38+
39+
void FileIndexRecord::addDeclOccurence(SymbolRoleSet Roles, unsigned Offset,
40+
const Decl *D,
41+
ArrayRef<SymbolRelation> Relations) {
42+
assert(D->isCanonicalDecl() &&
43+
"Occurrences should be associated with their canonical decl");
44+
addOccurrence(Decls, DeclOccurrence(Roles, Offset, D, Relations));
4245
}
4346

44-
void FileIndexRecord::print(llvm::raw_ostream &OS) const {
47+
void FileIndexRecord::addMacroOccurence(SymbolRoleSet Roles, unsigned Offset,
48+
const IdentifierInfo *Name,
49+
const MacroInfo *MI) {
50+
addOccurrence(Decls, DeclOccurrence(Roles, Offset, Name, MI));
51+
}
52+
53+
void FileIndexRecord::removeHeaderGuardMacros() {
54+
auto It =
55+
std::remove_if(Decls.begin(), Decls.end(), [](const DeclOccurrence &D) {
56+
if (const auto *MI = D.DeclOrMacro.dyn_cast<const MacroInfo *>())
57+
return MI->isUsedForHeaderGuard();
58+
return false;
59+
});
60+
Decls.erase(It, Decls.end());
61+
}
62+
63+
void FileIndexRecord::print(llvm::raw_ostream &OS, SourceManager &SM) const {
4564
OS << "DECLS BEGIN ---\n";
4665
for (auto &DclInfo : Decls) {
47-
const Decl *D = DclInfo.Dcl;
48-
SourceManager &SM = D->getASTContext().getSourceManager();
49-
SourceLocation Loc = SM.getFileLoc(D->getLocation());
50-
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
51-
OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' << PLoc.getLine()
52-
<< ':' << PLoc.getColumn();
53-
54-
if (auto ND = dyn_cast<NamedDecl>(D)) {
55-
OS << ' ' << ND->getDeclName();
66+
if (const auto *D = DclInfo.DeclOrMacro.dyn_cast<const Decl *>()) {
67+
SourceLocation Loc = SM.getFileLoc(D->getLocation());
68+
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
69+
OS << llvm::sys::path::filename(PLoc.getFilename()) << ':'
70+
<< PLoc.getLine() << ':' << PLoc.getColumn();
71+
72+
if (const auto *ND = dyn_cast<NamedDecl>(D)) {
73+
OS << ' ' << ND->getDeclName();
74+
}
75+
} else {
76+
const auto *MI = DclInfo.DeclOrMacro.get<const MacroInfo *>();
77+
SourceLocation Loc = SM.getFileLoc(MI->getDefinitionLoc());
78+
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
79+
OS << llvm::sys::path::filename(PLoc.getFilename()) << ':'
80+
<< PLoc.getLine() << ':' << PLoc.getColumn();
81+
OS << ' ' << DclInfo.MacroName->getName();
5682
}
5783

5884
OS << '\n';

clang/lib/Index/FileIndexRecord.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,21 @@ class FileIndexRecord {
4848
/// \param Relations the set of symbols related to this occurrence.
4949
void addDeclOccurence(SymbolRoleSet Roles, unsigned Offset, const Decl *D,
5050
ArrayRef<SymbolRelation> Relations);
51-
void print(llvm::raw_ostream &OS) const;
51+
52+
/// Adds an occurrence of the given macro at the supplied \c Offset.
53+
///
54+
/// \param Roles the roles the occurrence fulfills in this position.
55+
/// \param Offset the offset in the file of this occurrence.
56+
/// \param Name the name of the macro.
57+
/// \param MI the canonical declaration this is an occurrence of.
58+
void addMacroOccurence(SymbolRoleSet Roles, unsigned Offset,
59+
const IdentifierInfo *Name, const MacroInfo *MI);
60+
61+
/// Remove any macro occurrences for header guards. When preprocessing, this
62+
/// will only be accurate after HandleEndOfFile.
63+
void removeHeaderGuardMacros();
64+
65+
void print(llvm::raw_ostream &OS, SourceManager &SM) const;
5266
};
5367

5468
} // end namespace index

clang/lib/Index/IndexingAction.cpp

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ class IndexPPCallbacks final : public PPCallbacks {
5757
MacroNameTok.getLocation(),
5858
*MD.getMacroInfo());
5959
}
60+
61+
void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
62+
SourceRange Range) override {
63+
if (!MD.getMacroInfo()) // Ignore nonexistent macro.
64+
return;
65+
// Note: this is defined(M), not #define M
66+
IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
67+
MacroNameTok.getLocation(),
68+
*MD.getMacroInfo());
69+
}
70+
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
71+
const MacroDefinition &MD) override {
72+
if (!MD.getMacroInfo()) // Ignore non-existent macro.
73+
return;
74+
IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
75+
MacroNameTok.getLocation(),
76+
*MD.getMacroInfo());
77+
}
78+
void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
79+
const MacroDefinition &MD) override {
80+
if (!MD.getMacroInfo()) // Ignore nonexistent macro.
81+
return;
82+
IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
83+
MacroNameTok.getLocation(),
84+
*MD.getMacroInfo());
85+
}
6086
};
6187

6288
class IndexASTConsumer final : public ASTConsumer {
@@ -168,23 +194,54 @@ static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
168194
Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
169195
}
170196

171-
static void indexPreprocessorMacros(const Preprocessor &PP,
197+
static void indexPreprocessorMacro(const IdentifierInfo *II,
198+
const MacroInfo *MI,
199+
MacroDirective::Kind DirectiveKind,
200+
SourceLocation Loc,
201+
IndexDataConsumer &DataConsumer) {
202+
// When using modules, it may happen that we find #undef of a macro that
203+
// was defined in another module. In such case, MI may be nullptr, since
204+
// we only look for macro definitions in the current TU. In that case,
205+
// there is nothing to index.
206+
if (!MI)
207+
return;
208+
209+
// Skip implicit visibility change.
210+
if (DirectiveKind == MacroDirective::MD_Visibility)
211+
return;
212+
213+
auto Role = DirectiveKind == MacroDirective::MD_Define
214+
? SymbolRole::Definition
215+
: SymbolRole::Undefinition;
216+
DataConsumer.handleMacroOccurrence(II, MI, static_cast<unsigned>(Role), Loc);
217+
}
218+
219+
static void indexPreprocessorMacros(Preprocessor &PP,
172220
IndexDataConsumer &DataConsumer) {
173-
for (const auto &M : PP.macros())
174-
if (MacroDirective *MD = M.second.getLatest()) {
175-
auto *MI = MD->getMacroInfo();
176-
// When using modules, it may happen that we find #undef of a macro that
177-
// was defined in another module. In such case, MI may be nullptr, since
178-
// we only look for macro definitions in the current TU. In that case,
179-
// there is nothing to index.
180-
if (!MI)
181-
continue;
182-
183-
DataConsumer.handleMacroOccurrence(
184-
M.first, MD->getMacroInfo(),
185-
static_cast<unsigned>(index::SymbolRole::Definition),
186-
MD->getLocation());
221+
for (const auto &M : PP.macros()) {
222+
for (auto *MD = M.second.getLatest(); MD; MD = MD->getPrevious()) {
223+
indexPreprocessorMacro(M.first, MD->getMacroInfo(), MD->getKind(),
224+
MD->getLocation(), DataConsumer);
187225
}
226+
}
227+
}
228+
229+
static void indexPreprocessorModuleMacros(Preprocessor &PP,
230+
serialization::ModuleFile &Mod,
231+
IndexDataConsumer &DataConsumer) {
232+
for (const auto &M : PP.macros()) {
233+
if (M.second.getLatest() == nullptr) {
234+
for (auto *MM : PP.getLeafModuleMacros(M.first)) {
235+
auto *OwningMod = MM->getOwningModule();
236+
if (OwningMod && OwningMod->getASTFile() == Mod.File) {
237+
if (auto *MI = MM->getMacroInfo()) {
238+
indexPreprocessorMacro(M.first, MI, MacroDirective::MD_Define,
239+
MI->getDefinitionLoc(), DataConsumer);
240+
}
241+
}
242+
}
243+
}
244+
}
188245
}
189246

190247
void index::indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
@@ -231,8 +288,9 @@ void index::indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
231288
IndexCtx.setASTContext(Ctx);
232289
DataConsumer.initialize(Ctx);
233290

234-
if (Opts.IndexMacrosInPreprocessor)
235-
indexPreprocessorMacros(Reader.getPreprocessor(), DataConsumer);
291+
if (Opts.IndexMacrosInPreprocessor) {
292+
indexPreprocessorModuleMacros(Reader.getPreprocessor(), Mod, DataConsumer);
293+
}
236294

237295
for (const Decl *D : Reader.getModuleFileLevelDecls(Mod)) {
238296
IndexCtx.indexTopLevelDecl(D);

clang/lib/Index/IndexingContext.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,20 +495,55 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
495495
void IndexingContext::handleMacroDefined(const IdentifierInfo &Name,
496496
SourceLocation Loc,
497497
const MacroInfo &MI) {
498+
if (!shouldIndexMacroOccurrence(/*IsRef=*/false, Loc))
499+
return;
498500
SymbolRoleSet Roles = (unsigned)SymbolRole::Definition;
499501
DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
500502
}
501503

502504
void IndexingContext::handleMacroUndefined(const IdentifierInfo &Name,
503505
SourceLocation Loc,
504506
const MacroInfo &MI) {
507+
if (!shouldIndexMacroOccurrence(/*IsRef=*/false, Loc))
508+
return;
505509
SymbolRoleSet Roles = (unsigned)SymbolRole::Undefinition;
506510
DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
507511
}
508512

509513
void IndexingContext::handleMacroReference(const IdentifierInfo &Name,
510514
SourceLocation Loc,
511515
const MacroInfo &MI) {
516+
if (!shouldIndexMacroOccurrence(/*IsRef=*/true, Loc))
517+
return;
512518
SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
513519
DataConsumer.handleMacroOccurrence(&Name, &MI, Roles, Loc);
514520
}
521+
522+
bool IndexingContext::shouldIndexMacroOccurrence(bool IsRef,
523+
SourceLocation Loc) {
524+
if (!IndexOpts.IndexMacros)
525+
return false;
526+
527+
switch (IndexOpts.SystemSymbolFilter) {
528+
case IndexingOptions::SystemSymbolFilterKind::None:
529+
break;
530+
case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
531+
if (!IsRef)
532+
return true;
533+
break;
534+
case IndexingOptions::SystemSymbolFilterKind::All:
535+
return true;
536+
}
537+
538+
SourceManager &SM = Ctx->getSourceManager();
539+
FileID FID = SM.getFileID(SM.getFileLoc(Loc));
540+
if (FID.isInvalid())
541+
return false;
542+
543+
bool Invalid = false;
544+
const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
545+
if (Invalid || !SEntry.isFile())
546+
return false;
547+
548+
return SEntry.getFile().getFileCharacteristic() == SrcMgr::C_User;
549+
}

clang/lib/Index/IndexingContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class IndexingContext {
137137
private:
138138
bool shouldIgnoreIfImplicit(const Decl *D);
139139

140+
bool shouldIndexMacroOccurrence(bool IsRef, SourceLocation Loc);
141+
140142
bool handleDeclOccurrence(const Decl *D, SourceLocation Loc,
141143
bool IsRef, const Decl *Parent,
142144
SymbolRoleSet Roles,

clang/lib/Index/USRGeneration.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,15 +1103,14 @@ bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
11031103
bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
11041104
const SourceManager &SM,
11051105
SmallVectorImpl<char> &Buf) {
1106-
// Don't generate USRs for things with invalid locations.
1107-
if (MacroName.empty() || Loc.isInvalid())
1106+
if (MacroName.empty())
11081107
return true;
11091108

11101109
llvm::raw_svector_ostream Out(Buf);
11111110

11121111
// Assume that system headers are sane. Don't put source location
11131112
// information into the USR if the macro comes from a system header.
1114-
bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
1113+
bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
11151114

11161115
Out << getUSRSpacePrefix();
11171116
if (ShouldGenerateLocation)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11

22
void ModA_func(void);
3+
#define MODA_MACRO 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11

22
void SubModA_func(void);
3+
#define SUBMODA_MACRO 1

clang/test/Index/Core/Inputs/sys/system-head.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,18 @@ class SubCls1 : public Cls {
3434
// CHECK-NOT: [[@LINE+1]]:3 | class/C++ | SubCls1 |
3535
SubCls1 *f;
3636
};
37+
38+
// FIXME: this decl gets reported after the macro definitions, immediately
39+
// before the next declaration. Add a dummy declaration so that the checks work.
40+
void reset_parser();
41+
42+
// CHECK: [[@LINE+1]]:9 | macro/C | SYSTEM_MACRO | c:@macro@SYSTEM_MACRO | Def
43+
#define SYSTEM_MACRO 1
44+
// CHECK: [[@LINE+1]]:8 | macro/C | SYSTEM_MACRO | c:@macro@SYSTEM_MACRO | Undef
45+
#undef SYSTEM_MACRO
46+
// CHECK: [[@LINE+1]]:9 | macro/C | SYSTEM_MACRO | c:@macro@SYSTEM_MACRO | Def
47+
#define SYSTEM_MACRO int fromSystemMacro = 1
48+
49+
// CHECK-NOT: [[@LINE+2]]:1 | macro/C
50+
// CHECK: [[@LINE+1]]:1 | variable/C | fromSystemMacro
51+
SYSTEM_MACRO;

0 commit comments

Comments
 (0)