diff --git a/include/clad/Differentiator/TBRAnalyzer.h b/include/clad/Differentiator/TBRAnalyzer.h index 5ed94cb8d..38bdec597 100644 --- a/include/clad/Differentiator/TBRAnalyzer.h +++ b/include/clad/Differentiator/TBRAnalyzer.h @@ -83,25 +83,14 @@ class TBRAnalyzer : public clang::ConstStmtVisitor { /// Stores all the necessary information about one variable. Fundamental type /// variables need only one bit. An object/array needs a separate VarData for - /// every its field/element. Reference type variables have their own type for - /// convenience reasons and just point to the corresponding VarData. - /// UNDEFINED is used whenever the type of a node cannot be determined. + /// each field/element. Reference type variables store the clang::Expr* they + /// refer to. UNDEFINED is used whenever the type of a node cannot be determined. /// FIXME: Pointers to objects are considered OBJ_TYPE for simplicity. This /// approach might cause problems when the support for pointers is added. - /// FIXME: Only References to concrete variables are supported. Using - /// 'double& x = (cond ? a : b);' or 'double& x = arr[n*k]' (non-const index) - /// will lead to unpredictable behavior. - - /// FIXME: Different array elements are considered different variables - /// which makes the analysis way more complicated (both in terms of - /// readability and performance) when non-constant indices are used. Moreover, - /// in such cases we start assuming 'arr[k]' could be any element of arr. - /// The only scenario where analysing elements separately would make sense is - /// when an element with the same constant index is changed multiple times in - /// a row, which seems uncommon. It's worth considering analysing arrays as - /// whole structures instead (just one VarData for the whole array). + /// FIXME: Add support for references to call expression results. + /// 'double& x = f(b);' is not supported. struct VarData; using ObjMap = std::unordered_map; @@ -125,7 +114,7 @@ class TBRAnalyzer : public clang::ConstStmtVisitor { VarData() = default; /// Builds a VarData object (and its children) based on the provided type. - VarData(QualType QT); + VarData(const QualType QT); /// Erases all children VarData's of this VarData. void erase() { @@ -275,7 +264,7 @@ class TBRAnalyzer : public clang::ConstStmtVisitor { /// Stores modes in a stack (used to retrieve the old mode after entering /// a new one). - std::vector modeStack; + std::vector modeStack; ASTContext& m_Context; @@ -312,7 +301,7 @@ class TBRAnalyzer : public clang::ConstStmtVisitor { void setIsRequired(const clang::Expr* E, bool isReq = true); /// Returns the VarsData of the CFG block being visited. - VarsData& getCurBlockVarsData() { return *blockData[curBlockID]; } + VarsData& getCurBranch() { return *blockData[curBlockID]; } //// Modes Setters /// Sets the mode manually @@ -337,7 +326,9 @@ class TBRAnalyzer : public clang::ConstStmtVisitor { /// Destructor ~TBRAnalyzer() { for (auto varsData : blockData) { - delete varsData; + if (varsData) { + delete varsData; + } } }