Skip to content

Commit e2dc83c

Browse files
authored
Merge pull request #2803 from benlangmuir/index-macros-20210107
[20210107][index] Add macro definitions to the index store
2 parents 9915aab + 889306b commit e2dc83c

33 files changed

+594
-117
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,8 @@ def index_record_codegen_name : Flag<["-"], "index-record-codegen-name">, Flags<
620620
HelpText<"Record the codegen name for symbols">;
621621
def index_unit_output_path : Separate<["-"], "index-unit-output-path">, MetaVarName<"<path>">, Flags<[CC1Option]>,
622622
HelpText<"Use <path> as the output path for this compilation unit in the index unit file">;
623+
def index_ignore_macros : Flag<["-"], "index-ignore-macros">, Flags<[CC1Option]>,
624+
HelpText<"Ignore macros during indexing">;
623625

624626
// Make sure all other -ccc- options are rejected.
625627
def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>;

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ class FrontendOptions {
302302

303303
unsigned IndexIgnoreSystemSymbols : 1;
304304
unsigned IndexRecordCodegenName : 1;
305+
unsigned IndexIgnoreMacros : 1;
305306

306307
/// Output (and read) PCM files regardless of compiler errors.
307308
unsigned AllowPCMWithCompilerErrors : 1;

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/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5098,6 +5098,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
50985098
Args.AddLastArg(CmdArgs, options::OPT_index_ignore_system_symbols);
50995099
Args.AddLastArg(CmdArgs, options::OPT_index_record_codegen_name);
51005100
Args.AddLastArg(CmdArgs, options::OPT_index_unit_output_path);
5101+
Args.AddLastArg(CmdArgs, options::OPT_index_ignore_macros);
51015102

51025103
// If '-o' is passed along with '-fsyntax-only' pass it along the cc1
51035104
// invocation so that the index action knows what the out file is.

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
525525
Args.ClaimAllArgs(options::OPT_index_store_path);
526526
Args.ClaimAllArgs(options::OPT_index_ignore_system_symbols);
527527
Args.ClaimAllArgs(options::OPT_index_record_codegen_name);
528+
Args.ClaimAllArgs(options::OPT_index_ignore_macros);
528529

529530
/// Hack(tm) to ignore linking errors when we are doing ARC migration.
530531
if (Args.hasArg(options::OPT_ccc_arcmt_check,

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
18941894
Opts.IndexUnitOutputPath = std::string(Args.getLastArgValue(OPT_index_unit_output_path));
18951895
Opts.IndexIgnoreSystemSymbols = Args.hasArg(OPT_index_ignore_system_symbols);
18961896
Opts.IndexRecordCodegenName = Args.hasArg(OPT_index_record_codegen_name);
1897+
Opts.IndexIgnoreMacros = Args.hasArg(OPT_index_ignore_macros);
18971898

18981899
InputKind DashX(Language::Unknown);
18991900
if (const Arg *A = Args.getLastArg(OPT_x)) {

clang/lib/Index/ClangIndexRecordWriter.cpp

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ StringRef ClangIndexRecordWriter::getUSR(const Decl *D) {
2828
return Insert.first->second;
2929
}
3030

31+
StringRef ClangIndexRecordWriter::getUSR(const IdentifierInfo *Name,
32+
const MacroInfo *MI) {
33+
assert(Name && MI);
34+
auto Insert = USRByDecl.insert(std::make_pair(MI, StringRef()));
35+
if (Insert.second) {
36+
Insert.first->second = getUSRNonCached(Name, MI);
37+
}
38+
return Insert.first->second;
39+
}
40+
3141
StringRef ClangIndexRecordWriter::getUSRNonCached(const Decl *D) {
3242
SmallString<256> Buf;
3343
bool Ignore = generateUSRForDecl(D, Buf);
@@ -39,6 +49,19 @@ StringRef ClangIndexRecordWriter::getUSRNonCached(const Decl *D) {
3949
return StringRef(Ptr, USR.size());
4050
}
4151

52+
StringRef ClangIndexRecordWriter::getUSRNonCached(const IdentifierInfo *Name,
53+
const MacroInfo *MI) {
54+
SmallString<256> Buf;
55+
bool Ignore = generateUSRForMacro(Name->getName(), MI->getDefinitionLoc(),
56+
Ctx.getSourceManager(), Buf);
57+
if (Ignore)
58+
return StringRef();
59+
StringRef USR = Buf.str();
60+
char *Ptr = Allocator.Allocate<char>(USR.size());
61+
std::copy(USR.begin(), USR.end(), Ptr);
62+
return StringRef(Ptr, USR.size());
63+
}
64+
4265
ClangIndexRecordWriter::ClangIndexRecordWriter(ASTContext &Ctx,
4366
RecordingOptions Opts)
4467
: Impl(Opts.DataDirPath), Ctx(Ctx), RecordOpts(std::move(Opts)),
@@ -74,47 +97,63 @@ bool ClangIndexRecordWriter::writeRecord(StringRef Filename,
7497
return std::make_pair(LineNo, ColNo);
7598
};
7699

100+
llvm::DenseMap<const MacroInfo *, const IdentifierInfo *> MacroNames;
101+
77102
for (auto &Occur : IdxRecord.getDeclOccurrencesSortedByOffset()) {
78103
unsigned Line, Col;
79104
std::tie(Line, Col) = getLineCol(Occur.Offset);
80105
SmallVector<writer::SymbolRelation, 3> Related;
81106
Related.reserve(Occur.Relations.size());
82107
for (auto &Rel : Occur.Relations)
83108
Related.push_back(writer::SymbolRelation{Rel.RelatedSymbol, Rel.Roles});
109+
if (Occur.MacroName)
110+
MacroNames[Occur.DeclOrMacro.get<const MacroInfo *>()] = Occur.MacroName;
84111

85-
Impl.addOccurrence(Occur.Dcl, Occur.Roles, Line, Col, Related);
112+
Impl.addOccurrence(Occur.DeclOrMacro.getOpaqueValue(), Occur.Roles, Line,
113+
Col, Related);
86114
}
87115

88116
PrintingPolicy Policy(Ctx.getLangOpts());
89117
Policy.SuppressTemplateArgsInCXXConstructors = true;
90118

91119
auto Result = Impl.endRecord(Error,
92120
[&](writer::OpaqueDecl OD, SmallVectorImpl<char> &Scratch) {
93-
const Decl *D = static_cast<const Decl *>(OD);
94-
auto Info = getSymbolInfo(D);
95-
96121
writer::Symbol Sym;
97-
Sym.SymInfo = Info;
98-
99-
auto *ND = dyn_cast<NamedDecl>(D);
100-
if (ND) {
101-
llvm::raw_svector_ostream OS(Scratch);
102-
DeclarationName DeclName = ND->getDeclName();
103-
if (!DeclName.isEmpty())
104-
DeclName.print(OS, Policy);
122+
auto DeclOrMacro =
123+
llvm::PointerUnion<const Decl *, const MacroInfo *>::getFromOpaqueValue(
124+
const_cast<void *>(OD));
125+
if (auto *MI = DeclOrMacro.dyn_cast<const MacroInfo *>()) {
126+
auto *II = MacroNames[MI];
127+
assert(II);
128+
Sym.SymInfo = getSymbolInfoForMacro(*MI);
129+
Sym.Name = II->getName();
130+
Sym.USR = getUSR(II, MI);
131+
assert(!Sym.USR.empty() && "Recorded macro without USR!");
132+
} else {
133+
const Decl *D = DeclOrMacro.get<const Decl *>();
134+
Sym.SymInfo = getSymbolInfo(D);
135+
136+
auto *ND = dyn_cast<NamedDecl>(D);
137+
if (ND) {
138+
llvm::raw_svector_ostream OS(Scratch);
139+
DeclarationName DeclName = ND->getDeclName();
140+
if (!DeclName.isEmpty())
141+
DeclName.print(OS, Policy);
142+
}
143+
unsigned NameLen = Scratch.size();
144+
Sym.Name = StringRef(Scratch.data(), NameLen);
145+
146+
Sym.USR = getUSR(D);
147+
assert(!Sym.USR.empty() && "Recorded decl without USR!");
148+
149+
if (ASTNameGen && ND) {
150+
llvm::raw_svector_ostream OS(Scratch);
151+
ASTNameGen->writeName(ND, OS);
152+
}
153+
unsigned CGNameLen = Scratch.size() - NameLen;
154+
Sym.CodeGenName = StringRef(Scratch.data() + NameLen, CGNameLen);
105155
}
106-
unsigned NameLen = Scratch.size();
107-
Sym.Name = StringRef(Scratch.data(), NameLen);
108156

109-
Sym.USR = getUSR(D);
110-
assert(!Sym.USR.empty() && "Recorded decl without USR!");
111-
112-
if (ASTNameGen && ND) {
113-
llvm::raw_svector_ostream OS(Scratch);
114-
ASTNameGen->writeName(ND, OS);
115-
}
116-
unsigned CGNameLen = Scratch.size() - NameLen;
117-
Sym.CodeGenName = StringRef(Scratch.data() + NameLen, CGNameLen);
118157
return Sym;
119158
});
120159

clang/lib/Index/ClangIndexRecordWriter.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
namespace clang {
2020
class ASTContext;
2121
class Decl;
22+
class IdentifierInfo;
23+
class MacroInfo;
2224

2325
namespace index {
2426
class FileIndexRecord;
@@ -31,7 +33,7 @@ class ClangIndexRecordWriter {
3133

3234
std::unique_ptr<ASTNameGenerator> ASTNameGen;
3335
llvm::BumpPtrAllocator Allocator;
34-
llvm::DenseMap<const Decl *, StringRef> USRByDecl;
36+
llvm::DenseMap<const void *, StringRef> USRByDecl;
3537
IndexRecordHasher Hasher;
3638

3739
public:
@@ -44,9 +46,11 @@ class ClangIndexRecordWriter {
4446
bool writeRecord(StringRef Filename, const FileIndexRecord &Record,
4547
std::string &Error, std::string *RecordFile = nullptr);
4648
StringRef getUSR(const Decl *D);
49+
StringRef getUSR(const IdentifierInfo *Name, const MacroInfo *MI);
4750

4851
private:
4952
StringRef getUSRNonCached(const Decl *D);
53+
StringRef getUSRNonCached(const IdentifierInfo *Name, const MacroInfo *MI);
5054
};
5155

5256
} // end namespace index

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

0 commit comments

Comments
 (0)