]> granicus.if.org Git - clang/commitdiff
[analyzer] Refactor PathDiagnosticLocation: Pre-compute Range and Location with gen...
authorAnna Zaks <ganna@apple.com>
Tue, 20 Sep 2011 01:51:40 +0000 (01:51 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 20 Sep 2011 01:51:40 +0000 (01:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140131 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
lib/StaticAnalyzer/Core/PathDiagnostic.cpp

index 1b16ec50a052e0208781a57079caa69a648b2f1e..0e6b75278b5773945601890f70580ff7926c7d51 100644 (file)
@@ -27,6 +27,7 @@ class BinaryOperator;
 class CompoundStmt;
 class Decl;
 class LocationContext;
+class ParentMap;
 class ProgramPoint;
 class SourceManager;
 class Stmt;
@@ -79,10 +80,12 @@ protected:
 
 class PathDiagnosticRange : public SourceRange {
 public:
-  const bool isPoint;
+  bool isPoint;
 
   PathDiagnosticRange(const SourceRange &R, bool isP = false)
     : SourceRange(R), isPoint(isP) {}
+
+  PathDiagnosticRange() : isPoint(false) {}
 };
 
 class PathDiagnosticLocation {
@@ -93,24 +96,36 @@ private:
   const Decl *D;
   const SourceManager *SM;
   const LocationContext *LC;
+  FullSourceLoc Loc;
+  PathDiagnosticRange Range;
+
+  FullSourceLoc genLocation(const ParentMap *PM=0) const;
+  PathDiagnosticRange genRange(const ParentMap *PM=0) const;
+
 public:
   PathDiagnosticLocation()
-    : K(SingleLocK), S(0), D(0), SM(0), LC(0) {}
+    : K(SingleLocK), S(0), D(0), SM(0), LC(0) {
+  }
 
   PathDiagnosticLocation(FullSourceLoc L)
-    : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()), LC(0) {}
+    : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()), LC(0),
+      Loc(genLocation()), Range(genRange()) {
+  }
 
   PathDiagnosticLocation(SourceLocation L, const SourceManager &sm,
                          Kind kind = SingleLocK)
-    : K(kind), R(L, L), S(0), D(0), SM(&sm), LC(0) {}
+    : K(kind), R(L, L), S(0), D(0), SM(&sm), LC(0),
+      Loc(genLocation()), Range(genRange()) {
+  }
 
   PathDiagnosticLocation(const Stmt *s,
                          const SourceManager &sm,
-                         const LocationContext *lc)
-    : K(StmtK), S(s), D(0), SM(&sm), LC(lc) {}
+                         const LocationContext *lc);
 
   PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
-    : K(DeclK), S(0), D(d), SM(&sm), LC(0) {}
+    : K(DeclK), S(0), D(d), SM(&sm), LC(0),
+      Loc(genLocation()), Range(genRange()) {
+  }
 
   // Create a location for the beginning of the statement.
   static PathDiagnosticLocation createBeginStmt(const Stmt *S,
@@ -167,8 +182,14 @@ public:
     return SM != 0;
   }
 
-  FullSourceLoc asLocation() const;
-  PathDiagnosticRange asRange() const;
+  FullSourceLoc asLocation() const {
+    return Loc;
+  }
+
+  PathDiagnosticRange asRange() const {
+    return Range;
+  }
+
   const Stmt *asStmt() const { assert(isValid()); return S; }
   const Decl *asDecl() const { assert(isValid()); return D; }
 
index 1faace5464daa82ed8b8a75f89b0483cfc68557a..40b73deacb94b0ab6f052f7e476232d3d91f40cf 100644 (file)
@@ -131,32 +131,40 @@ void PathDiagnosticClient::HandlePathDiagnostic(const PathDiagnostic *D) {
 //===----------------------------------------------------------------------===//
 
 static SourceLocation getValidSourceLocation(const Stmt* S,
-                                             const LocationContext *LC) {
-  assert(LC);
+                                             const ParentMap &PM) {
   SourceLocation L = S->getLocStart();
 
   // S might be a temporary statement that does not have a location in the
   // source code, so find an enclosing statement and use it's location.
-  if (!L.isValid()) {
-    ParentMap & PM = LC->getParentMap();
-
-    while (!L.isValid()) {
-      S = PM.getParent(S);
-      L = S->getLocStart();
-    }
+  while (!L.isValid()) {
+    S = PM.getParent(S);
+    L = S->getLocStart();
   }
 
   return L;
 }
 
+PathDiagnosticLocation::PathDiagnosticLocation(const Stmt *s,
+                                               const SourceManager &sm,
+                                               const LocationContext *lc)
+  : K(StmtK), S(s), D(0), SM(&sm), LC(lc)
+{
+  const ParentMap* PM = 0;
+  if (lc)
+    PM = &lc->getParentMap();
+
+  Loc = genLocation(PM);
+  Range = genRange(PM);
+}
+
 PathDiagnosticLocation
   PathDiagnosticLocation::createBeginStmt(const Stmt *S,
                                           const SourceManager &SM,
                                           const LocationContext *LC) {
-  return PathDiagnosticLocation(getValidSourceLocation(S, LC), SM, SingleLocK);
+  return PathDiagnosticLocation(getValidSourceLocation(S, LC->getParentMap()),
+                                SM, SingleLocK);
 }
 
-
 PathDiagnosticLocation
   PathDiagnosticLocation::createOperatorLoc(const BinaryOperator *BO,
                                             const SourceManager &SM) {
@@ -246,7 +254,8 @@ PathDiagnosticLocation PathDiagnosticLocation::createSingleLocation(
   return PathDiagnosticLocation(L, L.getManager(), SingleLocK);
 }
 
-FullSourceLoc PathDiagnosticLocation::asLocation() const {
+FullSourceLoc
+  PathDiagnosticLocation::genLocation(const ParentMap *PM) const {
   assert(isValid());
   // Note that we want a 'switch' here so that the compiler can warn us in
   // case we add more cases.
@@ -255,7 +264,7 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const {
     case RangeK:
       break;
     case StmtK:
-      return FullSourceLoc(getValidSourceLocation(S, LC),
+      return FullSourceLoc(getValidSourceLocation(S, LC->getParentMap()),
                            const_cast<SourceManager&>(*SM));
     case DeclK:
       return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
@@ -264,7 +273,8 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const {
   return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM));
 }
 
-PathDiagnosticRange PathDiagnosticLocation::asRange() const {
+PathDiagnosticRange
+  PathDiagnosticLocation::genRange(const ParentMap *PM) const {
   assert(isValid());
   // Note that we want a 'switch' here so that the compiler can warn us in
   // case we add more cases.
@@ -299,7 +309,7 @@ PathDiagnosticRange PathDiagnosticLocation::asRange() const {
         case Stmt::BinaryConditionalOperatorClass:
         case Stmt::ConditionalOperatorClass:
         case Stmt::ObjCForCollectionStmtClass: {
-          SourceLocation L = getValidSourceLocation(S, LC);
+          SourceLocation L = getValidSourceLocation(S, LC->getParentMap());
           return SourceRange(L, L);
         }
       }