From: Ted Kremenek Date: Mon, 6 Apr 2009 22:33:35 +0000 (+0000) Subject: PathDiagnosticLocation now also wraps Decls. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fea5f5a1e8fe558d716ddeddf1aecf63f2e9a54f;p=clang PathDiagnosticLocation now also wraps Decls. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68470 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index bed2e0e3c9..33adcc99ad 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -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; } }; diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index 69b11fb5da..da007c16ec 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -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 @@ -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(*SM)); + case DeclK: + return FullSourceLoc(D->getLocation(), const_cast(*SM)); } return FullSourceLoc(R.getBegin(), const_cast(*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(D)) + return MD->getSourceRange(); + if (const FunctionDecl *FD = dyn_cast(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; + } +} + +