================
@@ -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.
----------------
NagyDonat wrote:

Thanks for the info!

I think I can answer my own question now: _"Why do you have a special visit 
method for `IfStmt` and not for other similar statements?"_ – because `if` can 
be an `if constexpr` and `If->getNondiscardedCase()` is relevant only for `if 
constexpr`.

For some reason I assumed that the traversal that you're using prunes any 
branch with a constant false condition and would also skip e.g. `if (false) 
{...}` or `while (false) {...}` – but if it only skips `if constexpr (false) 
{...}` then it is clear that you only need special logic for `IfStmt`.

Perhaps mention in the comments that this special visitor is needed to properly 
handle `if constexpr` -- it would be helpful for the readers :sweat_smile:




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