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