Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -49,6 +49,8 @@ return !T.isNull() && !T->isVoidType(); } + mutable unsigned Complexity = 0; + public: virtual ~SymExpr() = default; @@ -85,7 +87,7 @@ symbol_iterator symbol_begin() const { return symbol_iterator(this); } static symbol_iterator symbol_end() { return symbol_iterator(); } - unsigned computeComplexity() const; + virtual unsigned computeComplexity() const; /// Find the region from which this symbol originates. /// @@ -127,6 +129,10 @@ SymbolID getSymbolID() const { return Sym; } + unsigned computeComplexity() const override { + return 1; + }; + // Implement isa support. static inline bool classof(const SymExpr *SE) { Kind k = SE->getKind(); Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -270,6 +270,14 @@ // Otherwise, 'To' should also be a valid type. } + unsigned computeComplexity() const { + if (Complexity == 0) { + for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) + ++Complexity; + } + return Complexity; + } + QualType getType() const override { return ToTy; } const SymExpr *getOperand() const { return Operand; } @@ -313,6 +321,15 @@ BinaryOperator::Opcode getOpcode() const { return Op; } + + unsigned computeComplexity() const { + if (Complexity == 0) { + for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) + ++Complexity; + } + return Complexity; + } + // Implement isa support. static bool classof(const SymExpr *SE) { Kind k = SE->getKind(); Index: lib/StaticAnalyzer/Core/SymbolManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/SymbolManager.cpp +++ lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -160,10 +160,12 @@ } unsigned SymExpr::computeComplexity() const { - unsigned R = 0; - for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) - R++; - return R; + if (Complexity == 0) { + for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) + Complexity += (*I)->computeComplexity(); + } + + return Complexity; } const SymbolRegionValue*