]> granicus.if.org Git - clang/commitdiff
PathDiagnosticLocation now also wraps Decls.
authorTed Kremenek <kremenek@apple.com>
Mon, 6 Apr 2009 22:33:35 +0000 (22:33 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 6 Apr 2009 22:33:35 +0000 (22:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68470 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathDiagnostic.h
lib/Analysis/PathDiagnostic.cpp

index bed2e0e3c9fc7a6bea89e45fb23ee2819fb676aa..33adcc99ad7344ff879ed985d00fb8578f15d6ff 100644 (file)
@@ -31,6 +31,7 @@ namespace clang {
 
 class PathDiagnostic;
 class Stmt;
+class Decl;
 
 class PathDiagnosticClient : public DiagnosticClient  {
 public:
@@ -54,35 +55,40 @@ public:
   
 class PathDiagnosticLocation {
 private:
-  enum Kind { Range, SingleLoc, Statement } K;
+  enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
   SourceRange R;
   const Stmt *S;
+  const Decl *D;
   const SourceManager *SM;
 public:
   PathDiagnosticLocation()
-    : K(SingleLoc), S(0), SM(0) {}
+    : K(SingleLocK), S(0), D(0), SM(0) {}
   
   PathDiagnosticLocation(FullSourceLoc L)
-    : K(SingleLoc), R(L, L), S(0), SM(&L.getManager()) {}
+    : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()) {}
   
   PathDiagnosticLocation(const Stmt *s, const SourceManager &sm)
-    : K(Statement), S(s), SM(&sm) {}
+    : K(StmtK), S(s), D(0), SM(&sm) {}
   
   PathDiagnosticLocation(SourceRange r, const SourceManager &sm)
-    : K(Range), R(r), S(0), SM(&sm) {}
+    : K(RangeK), R(r), S(0), D(0), SM(&sm) {}
+  
+  PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
+    : K(DeclK), S(0), D(d), SM(&sm) {}
   
   bool operator==(const PathDiagnosticLocation &X) const {
-    return K == X.K && R == X.R && S == X.S;
+    return K == X.K && R == X.R && S == X.S && D == X.D;
   }
   
   bool operator!=(const PathDiagnosticLocation &X) const {
-    return K != X.K || R != X.R || S != X.S;
+    return K != X.K || R != X.R || S != X.S || D != X.D;;
   }
   
   PathDiagnosticLocation& operator=(const PathDiagnosticLocation &X) {
     K = X.K;
     R = X.R;
     S = X.S;
+    D = X.D;
     SM = X.SM;
     return *this;
   }
@@ -94,20 +100,15 @@ public:
   FullSourceLoc asLocation() const;
   SourceRange asRange() const;
   const Stmt *asStmt() const { assert(isValid()); return S; }
+  const Decl *asDecl() const { assert(isValid()); return D; }
   
-  bool hasRange() const { return K == Statement || K == Range; }
+  bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
   
   void invalidate() {
     *this = PathDiagnosticLocation();
   }
   
-  void flatten() {
-    if (K == Statement) {
-      R = asRange();
-      K = Range;
-      S = 0;
-    }    
-  }
+  void flatten();
   
   const SourceManager& getManager() const { assert(isValid()); return *SM; }
 };
index 69b11fb5dacb80e59330e69ab1fce65d33147f0e..da007c16ec47ff1b3e9358df78fbb30d0cebea6e 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "clang/Analysis/PathDiagnostic.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Casting.h"
 #include <sstream>
@@ -144,11 +146,13 @@ FullSourceLoc PathDiagnosticLocation::asLocation() const {
   // Note that we want a 'switch' here so that the compiler can warn us in
   // case we add more cases.
   switch (K) {
-    case SingleLoc:
-    case Range:
+    case SingleLocK:
+    case RangeK:
       break;
-    case Statement:
+    case StmtK:
       return FullSourceLoc(S->getLocStart(), const_cast<SourceManager&>(*SM));
+    case DeclK:
+      return FullSourceLoc(D->getLocation(), const_cast<SourceManager&>(*SM));
   }
   
   return FullSourceLoc(R.getBegin(), const_cast<SourceManager&>(*SM));
@@ -159,13 +163,39 @@ SourceRange PathDiagnosticLocation::asRange() const {
   // Note that we want a 'switch' here so that the compiler can warn us in
   // case we add more cases.
   switch (K) {
-    case SingleLoc:
-    case Range:
+    case SingleLocK:
+    case RangeK:
       break;
-    case Statement:
+    case StmtK:
       return S->getSourceRange();
+    case DeclK:
+      if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+        return MD->getSourceRange();
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+        return FD->getBody()->getSourceRange();
+      else {
+        SourceLocation L = D->getLocation();
+        return SourceRange(L, L);
+      }
   }
   
   return R;
 }
 
+void PathDiagnosticLocation::flatten() {
+  if (K == StmtK) {
+    R = asRange();
+    K = RangeK;
+    S = 0;
+    D = 0;
+  }
+  else if (K == DeclK) {
+    SourceLocation L = D->getLocation();
+    R = SourceRange(L, L);
+    K = SingleLocK;
+    S = 0;
+    D = 0;
+  }
+}
+
+