================
@@ -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

Reply via email to