================
@@ -409,6 +411,75 @@ CrossTranslationUnitContext::getCrossTUDefinition(const
VarDecl *VD,
DisplayCTUProgress);
}
+void CrossTranslationUnitContext::importReferencedInitializers(
+ const Stmt *S, StringRef CrossTUDir, StringRef IndexName,
+ bool DisplayCTUProgress) {
+ class InitializerVisitor
+ : public ConstEvaluatedExprVisitor<InitializerVisitor> {
+ CrossTranslationUnitContext &CTU;
+ StringRef CrossTUDir;
+ StringRef IndexName;
+ bool DisplayCTUProgress;
+ llvm::SmallPtrSet<const VarDecl *, 8> Visited;
+
+ void importInitializer(const VarDecl *VD) {
+ if (!VD || !VD->hasGlobalStorage() || !shouldImport(VD, Context) ||
+ !Visited.insert(VD->getCanonicalDecl()).second)
+ return;
+
+ const Expr *Init = VD->getAnyInitializer();
+ if (!Init && (VD->hasExternalStorage() || VD->isStaticDataMember())) {
+ auto Imported = CTU.getCrossTUDefinition(VD, CrossTUDir, IndexName,
+ DisplayCTUProgress);
+ if (!Imported) {
+ llvm::handleAllErrors(
+ Imported.takeError(), [&](const IndexError &IE) {
+ CTU.emitCrossTUDiagnostics(IE, VD->getLocation());
+ });
+ return;
+ }
+ Init = (*Imported)->getAnyInitializer();
+ }
+ if (Init)
+ Visit(Init);
+ }
+
+ public:
+ InitializerVisitor(CrossTranslationUnitContext &CTU, ASTContext &Context,
+ StringRef CrossTUDir, StringRef IndexName,
+ bool DisplayCTUProgress)
+ : ConstEvaluatedExprVisitor<InitializerVisitor>(Context), CTU(CTU),
+ CrossTUDir(CrossTUDir), IndexName(IndexName),
+ DisplayCTUProgress(DisplayCTUProgress) {}
+
+ void VisitDeclRefExpr(const DeclRefExpr *E) {
+ importInitializer(dyn_cast<VarDecl>(E->getDecl()));
+ }
+
+ void VisitMemberExpr(const MemberExpr *E) {
+ importInitializer(dyn_cast<VarDecl>(E->getMemberDecl()));
+ Visit(E->getBase());
+ }
+
+ void VisitIfStmt(const IfStmt *If) {
+ if (auto Selected = If->getNondiscardedCase(Context)) {
+ // The init-statement executes even when a body is discarded.
----------------
relaxcn wrote:
The generic `VisitStmt` walks the statement's children, including the
initializer and condition-variable declarations of ordinary `if`, `for`,
`switch`, and `while` statements.
The reason why I rewrite the visitor for `IfStmt` is because:
The base visitor visits discarded statements by default. Simply overriding
`shouldVisitDiscardedStmt()` to return false would instead make its
`VisitIfStmt` visit only the selected body and return instead of the
`init-statement`.
I have added the corresponding tests.
https://github.com/llvm/llvm-project/pull/231393
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits