[clang] Fieldregion descript name (PR #112313)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 15 05:11:24 PDT 2024


================
@@ -751,12 +751,27 @@ std::string MemRegion::getDescriptiveName(bool UseQuotes) const {
   }
 
   // Get variable name.
-  if (R && R->canPrintPrettyAsExpr()) {
-    R->printPrettyAsExpr(os);
-    if (UseQuotes)
-      return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
-    else
+  if (R) {
+    // MemRegion can be pretty printed.
+    if (R->canPrintPrettyAsExpr()) {
+      R->printPrettyAsExpr(os);
+      if (UseQuotes)
+        return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str();
       return (llvm::Twine(os.str()) + ArrayIndices).str();
+    }
+
+    // FieldRegion may have ElementRegion as SuperRegion.
+    if (const clang::ento::FieldRegion *FR =
+            R->getAs<clang::ento::FieldRegion>()) {
+      std::string Super = FR->getSuperRegion()->getDescriptiveName(false);
----------------
T-Gruber wrote:

I completely agree with you. It really is a bit messy and confusing. I'm currently working with a workaround that looks like this:

```Cpp
std::string getDescriptiveNameFixed(const clang::ento::MemRegion *R) {

  if (const auto *ER = R->getAs<clang::ento::ElementRegion>()) {
    std::string ArrayIndices;

    // Index is a ConcreteInt.
    if (auto CI = ER->getIndex().getAs<clang::ento::nonloc::ConcreteInt>()) {
      llvm::SmallString<2> Idx;
      CI->getValue().toString(Idx);
      ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str();
    }
    // Index is symbolic, but may have a descriptive name.
    else {
      auto SI = ER->getIndex().getAs<clang::ento::nonloc::SymbolVal>();
      if (!SI)
        return "";

      const clang::ento::MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
      if (!OR)
        return "";

      std::string Idx = OR->getDescriptiveName(false);
      if (Idx.empty())
        return "";

      ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str();
    }

    // Get descriptive name of SuperRegion.
    std::string Super = getDescriptiveNameFixed(ER->getSuperRegion());
    if (Super.empty())
      return "";
    return Super + ArrayIndices;
  }

  if (const auto *FR = R->getAs<clang::ento::FieldRegion>()) {
    // Get descriptive name of SuperRegion.
    std::string Super = getDescriptiveNameFixed(FR->getSuperRegion());
    if (Super.empty())
      return "";
    return Super + "." + FR->getDecl()->getNameAsString();
  }

  // MemRegion is one of: NonParamVarRegion, ParamVarRegion, ObjCIvarRegion,
  // CXXBaseObjectRegion or CXXDerivedObjectRegion.
  if (R && R->canPrintPrettyAsExpr()) {
    llvm::SmallString<50> buf;
    llvm::raw_svector_ostream os(buf);
    R->printPrettyAsExpr(os);
    return os.str().str();
  }

  return "";
}
```

In my opinion it's much clearer and easier to understand. What do you think?

https://github.com/llvm/llvm-project/pull/112313


More information about the cfe-commits mailing list