Skip to content

Commit 342ab3b

Browse files
committed
Drop declares object from index
1 parent 18fd12f commit 342ab3b

3 files changed

Lines changed: 47 additions & 83 deletions

File tree

‎cpp2rust/converter/rules/rules_loader.cpp‎

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <clang/Basic/LangOptions.h>
99
#include <clang/Lex/Lexer.h>
1010
#include <clang/Lex/Preprocessor.h>
11+
#include <clang/Sema/Lookup.h>
1112
#include <clang/Sema/Sema.h>
1213
#include <llvm/ADT/DenseSet.h>
1314
#include <llvm/ADT/STLExtras.h>
@@ -203,6 +204,7 @@ class RuleUsageCollector
203204
AddTemplateArgs(spec->getTemplateArgs().asArray());
204205
}
205206
AddSpecialMembers(record);
207+
AddIterator(type, record);
206208
}
207209
return;
208210
}
@@ -226,6 +228,46 @@ class RuleUsageCollector
226228
}
227229
}
228230

231+
void AddIterator(clang::QualType type, const clang::CXXRecordDecl *record) {
232+
auto *std_namespace = sema_.getStdNamespace();
233+
if (!std_namespace ||
234+
!ctx_.getSourceManager().isInSystemHeader(record->getLocation())) {
235+
return;
236+
}
237+
clang::ClassTemplateDecl *traits = nullptr;
238+
for (auto *decl :
239+
std_namespace->lookup(&ctx_.Idents.get("iterator_traits"))) {
240+
if ((traits = llvm::dyn_cast<clang::ClassTemplateDecl>(decl))) {
241+
break;
242+
}
243+
}
244+
if (!traits) {
245+
return;
246+
}
247+
auto loc = record->getLocation();
248+
RuleDecls::Trial trial(sema_);
249+
clang::TemplateArgumentListInfo args(loc, loc);
250+
args.addArgument(
251+
clang::TemplateArgumentLoc(clang::TemplateArgument(type),
252+
ctx_.getTrivialTypeSourceInfo(type, loc)));
253+
auto instance = sema_.CheckTemplateIdType(
254+
clang::ElaboratedTypeKeyword::None, clang::TemplateName(traits), loc,
255+
args, /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);
256+
if (instance.isNull() || !sema_.isCompleteType(loc, instance) ||
257+
trial.failed()) {
258+
return;
259+
}
260+
auto *instance_record = instance->getAsCXXRecordDecl();
261+
if (!instance_record) {
262+
return;
263+
}
264+
clang::LookupResult category(sema_, &ctx_.Idents.get("iterator_category"),
265+
loc, clang::Sema::LookupMemberName);
266+
if (sema_.LookupQualifiedName(category, instance_record)) {
267+
AddKey(kAnyIteratorKey);
268+
}
269+
}
270+
229271
void AddTemplateArgs(llvm::ArrayRef<clang::TemplateArgument> args) {
230272
for (const auto &arg : args) {
231273
switch (arg.getKind()) {
@@ -299,31 +341,8 @@ unsigned CxxStandard(const clang::LangOptions &opts) {
299341
return 11;
300342
}
301343

302-
bool IsDeclared(clang::ASTContext &ctx, llvm::StringRef key) {
303-
const clang::DeclContext *scope = ctx.getTranslationUnitDecl();
304-
while (true) {
305-
auto [name, rest] = key.split('/');
306-
auto found = scope->lookup(&ctx.Idents.get(name));
307-
if (rest.empty()) {
308-
return !found.empty();
309-
}
310-
scope = nullptr;
311-
for (auto decl : found) {
312-
if (llvm::isa<clang::NamespaceDecl, clang::TagDecl>(decl)) {
313-
scope = llvm::cast<clang::DeclContext>(decl);
314-
break;
315-
}
316-
}
317-
if (!scope) {
318-
return false;
319-
}
320-
key = rest;
321-
}
322-
}
323-
324344
std::string BuildRulesEpilogue(const std::unordered_set<std::string> &keys,
325-
clang::ASTContext &ctx) {
326-
const auto &opts = ctx.getLangOpts();
345+
const clang::LangOptions &opts) {
327346
bool is_cxx = opts.CPlusPlus;
328347
const auto &index = is_cxx ? CxxIndex() : CIndex();
329348
unsigned standard = is_cxx ? CxxStandard(opts) : 0;
@@ -352,13 +371,6 @@ std::string BuildRulesEpilogue(const std::unordered_set<std::string> &keys,
352371
})) {
353372
continue;
354373
}
355-
if (auto declared = rule->getArray("declares");
356-
declared &&
357-
!llvm::all_of(*declared, [&](const llvm::json::Value &name) {
358-
return IsDeclared(ctx, *name.getAsString());
359-
})) {
360-
continue;
361-
}
362374
out += WrapRule(*rule, is_cxx);
363375
}
364376
}
@@ -553,7 +565,7 @@ void PragmaHandler::HandlePragma(clang::Preprocessor &PP,
553565
RuleUsageCollector collector(CI_.getSema(), keys);
554566
collector.TraverseDecl(ctx.getTranslationUnitDecl());
555567

556-
auto text = BuildRulesEpilogue(keys, ctx);
568+
auto text = BuildRulesEpilogue(keys, ctx.getLangOpts());
557569
log() << "rules loaded for this translation unit:\n" << text;
558570
auto rules_file = src_mgr.createFileID(
559571
llvm::MemoryBuffer::getMemBufferCopy(text, "<cpp2rust-rules>"),

‎cpp2rust/converter/rules/rules_loader.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ inline constexpr const char *kPragmaName = "cpp2rust_rules";
2121

2222
inline constexpr const char *kAnyClassKey = "*";
2323

24+
inline constexpr const char *kAnyIteratorKey = "std/iterator_traits";
25+
2426
std::string ClassKey(const clang::NamedDecl *decl);
2527

2628
std::string MemberName(clang::DeclarationName name);

‎cpp2rust/rule_preprocessing/cpp_rule_indexer.cpp‎

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <clang/AST/Decl.h>
66
#include <clang/AST/DeclTemplate.h>
77
#include <clang/AST/ExprCXX.h>
8-
#include <clang/AST/RecursiveASTVisitor.h>
98
#include <clang/Basic/TokenKinds.h>
109
#include <clang/Frontend/ASTUnit.h>
1110
#include <clang/Tooling/Tooling.h>
@@ -134,55 +133,6 @@ std::string ClassOfParameters(const clang::Decl *rule) {
134133
return {};
135134
}
136135

137-
class DeclaredNames : public clang::RecursiveASTVisitor<DeclaredNames> {
138-
public:
139-
explicit DeclaredNames(const clang::SourceManager &sm) : sm_(sm) {}
140-
141-
bool
142-
VisitTemplateSpecializationType(clang::TemplateSpecializationType *type) {
143-
add(type->getTemplateName().getAsTemplateDecl());
144-
return true;
145-
}
146-
147-
bool VisitTagType(clang::TagType *type) {
148-
add(type->getDecl());
149-
return true;
150-
}
151-
152-
bool VisitDeclRefExpr(clang::DeclRefExpr *expr) {
153-
add(expr->getDecl());
154-
return true;
155-
}
156-
157-
bool VisitOverloadExpr(clang::OverloadExpr *expr) {
158-
if (expr->decls_begin() != expr->decls_end()) {
159-
add((*expr->decls_begin())->getUnderlyingDecl());
160-
}
161-
return true;
162-
}
163-
164-
std::unordered_set<std::string> names;
165-
166-
private:
167-
void add(const clang::NamedDecl *decl) {
168-
if (!decl || !sm_.isInSystemHeader(decl->getLocation())) {
169-
return;
170-
}
171-
if (auto key = RulesLoader::ClassKey(decl); !key.empty()) {
172-
names.insert(key);
173-
}
174-
}
175-
176-
const clang::SourceManager &sm_;
177-
};
178-
179-
std::unordered_set<std::string> DeclaredNamesOf(clang::ASTContext &ctx,
180-
const clang::Decl *rule) {
181-
DeclaredNames visitor(ctx.getSourceManager());
182-
visitor.TraverseDecl(const_cast<clang::Decl *>(rule));
183-
return std::move(visitor.names);
184-
}
185-
186136
const clang::Expr *RuleExpr(const clang::Decl *decl) {
187137
if (auto var = llvm::dyn_cast<clang::VarDecl>(decl)) {
188138
return var->getInit();
@@ -323,7 +273,7 @@ void IndexRuleFile(clang::ASTContext &ctx, const std::string &dir_name,
323273
auto text = clang::tooling::getText(range, ctx).str() + '\n';
324274
llvm::json::Object rule{{"dir", dir_name}, {"name", name}, {"text", text}};
325275
if (any_class) {
326-
rule["declares"] = llvm::json::Array(DeclaredNamesOf(ctx, decl));
276+
rule["requires"] = llvm::json::Array{RulesLoader::kAnyIteratorKey};
327277
} else if (auto required = RequiredClasses(decl, alias);
328278
!required.empty()) {
329279
rule["requires"] = llvm::json::Array(required);

0 commit comments

Comments
 (0)