summaryrefslogtreecommitdiff
path: root/include/clang/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis')
-rw-r--r--include/clang/Analysis/Analyses/PrintfFormatString.h279
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h3
-rw-r--r--include/clang/Analysis/AnalysisContext.h (renamed from include/clang/Analysis/PathSensitive/AnalysisContext.h)33
-rw-r--r--include/clang/Analysis/LocalCheckers.h63
-rw-r--r--include/clang/Analysis/ManagerRegistry.h53
-rw-r--r--include/clang/Analysis/PathDiagnostic.h494
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisManager.h149
-rw-r--r--include/clang/Analysis/PathSensitive/BasicValueFactory.h198
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h473
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h76
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h281
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.def38
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.h101
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h31
-rw-r--r--include/clang/Analysis/PathSensitive/ConstraintManager.h75
-rw-r--r--include/clang/Analysis/PathSensitive/Environment.h103
-rw-r--r--include/clang/Analysis/PathSensitive/ExplodedGraph.h432
-rw-r--r--include/clang/Analysis/PathSensitive/GRAuditor.h35
-rw-r--r--include/clang/Analysis/PathSensitive/GRBlockCounter.h50
-rw-r--r--include/clang/Analysis/PathSensitive/GRCoreEngine.h443
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h433
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h76
-rw-r--r--include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h40
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h751
-rw-r--r--include/clang/Analysis/PathSensitive/GRStateTrait.h148
-rw-r--r--include/clang/Analysis/PathSensitive/GRSubEngine.h75
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h85
-rw-r--r--include/clang/Analysis/PathSensitive/GRWorkList.h79
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h971
-rw-r--r--include/clang/Analysis/PathSensitive/SVals.h499
-rw-r--r--include/clang/Analysis/PathSensitive/SValuator.h91
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h220
-rw-r--r--include/clang/Analysis/PathSensitive/SymbolManager.h385
-rw-r--r--include/clang/Analysis/PathSensitive/ValueManager.h208
-rw-r--r--include/clang/Analysis/Support/Optional.h12
35 files changed, 300 insertions, 7183 deletions
diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h
new file mode 100644
index 000000000000..a4ad0b703708
--- /dev/null
+++ b/include/clang/Analysis/Analyses/PrintfFormatString.h
@@ -0,0 +1,279 @@
+//==- PrintfFormatStrings.h - Analysis of printf format strings --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Handling of format string in printf and friends. The structure of format
+// strings for fprintf() are described in C99 7.19.6.1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FPRINTF_FORMAT_H
+#define LLVM_CLANG_FPRINTF_FORMAT_H
+
+#include "clang/AST/CanonicalType.h"
+
+namespace clang {
+
+class ASTContext;
+
+namespace analyze_printf {
+
+class ArgTypeResult {
+public:
+ enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy,
+ WCStrTy };
+private:
+ const Kind K;
+ QualType T;
+ ArgTypeResult(bool) : K(InvalidTy) {}
+public:
+ ArgTypeResult(Kind k = UnknownTy) : K(k) {}
+ ArgTypeResult(QualType t) : K(SpecificTy), T(t) {}
+ ArgTypeResult(CanQualType t) : K(SpecificTy), T(t) {}
+
+ static ArgTypeResult Invalid() { return ArgTypeResult(true); }
+
+ bool isValid() const { return K != InvalidTy; }
+
+ const QualType *getSpecificType() const {
+ return K == SpecificTy ? &T : 0;
+ }
+
+ bool matchesType(ASTContext &C, QualType argTy) const;
+
+ bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
+
+ QualType getRepresentativeType(ASTContext &C) const;
+};
+
+class ConversionSpecifier {
+public:
+ enum Kind {
+ InvalidSpecifier = 0,
+ // C99 conversion specifiers.
+ dArg, // 'd'
+ iArg, // 'i',
+ oArg, // 'o',
+ uArg, // 'u',
+ xArg, // 'x',
+ XArg, // 'X',
+ fArg, // 'f',
+ FArg, // 'F',
+ eArg, // 'e',
+ EArg, // 'E',
+ gArg, // 'g',
+ GArg, // 'G',
+ aArg, // 'a',
+ AArg, // 'A',
+ IntAsCharArg, // 'c'
+ CStrArg, // 's'
+ VoidPtrArg, // 'p'
+ OutIntPtrArg, // 'n'
+ PercentArg, // '%'
+ // Objective-C specific specifiers.
+ ObjCObjArg, // '@'
+ // GlibC specific specifiers.
+ PrintErrno, // 'm'
+ // Specifier ranges.
+ IntArgBeg = dArg,
+ IntArgEnd = iArg,
+ UIntArgBeg = oArg,
+ UIntArgEnd = XArg,
+ DoubleArgBeg = fArg,
+ DoubleArgEnd = AArg,
+ C99Beg = IntArgBeg,
+ C99End = DoubleArgEnd,
+ ObjCBeg = ObjCObjArg,
+ ObjCEnd = ObjCObjArg
+ };
+
+ ConversionSpecifier()
+ : Position(0), kind(InvalidSpecifier) {}
+
+ ConversionSpecifier(const char *pos, Kind k)
+ : Position(pos), kind(k) {}
+
+ const char *getStart() const {
+ return Position;
+ }
+
+ llvm::StringRef getCharacters() const {
+ return llvm::StringRef(getStart(), getLength());
+ }
+
+ bool consumesDataArgument() const {
+ switch (kind) {
+ case PercentArg:
+ case PrintErrno:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
+ bool isIntArg() const { return kind >= dArg && kind <= iArg; }
+ bool isUIntArg() const { return kind >= oArg && kind <= XArg; }
+ bool isDoubleArg() const { return kind >= fArg && kind <= AArg; }
+ Kind getKind() const { return kind; }
+ unsigned getLength() const {
+ // Conversion specifiers currently only are represented by
+ // single characters, but we be flexible.
+ return 1;
+ }
+
+private:
+ const char *Position;
+ Kind kind;
+};
+
+enum LengthModifier {
+ None,
+ AsChar, // 'hh'
+ AsShort, // 'h'
+ AsLong, // 'l'
+ AsLongLong, // 'll', 'q' (BSD, deprecated)
+ AsIntMax, // 'j'
+ AsSizeT, // 'z'
+ AsPtrDiff, // 't'
+ AsLongDouble, // 'L'
+ AsWideChar = AsLong // for '%ls'
+};
+
+class OptionalAmount {
+public:
+ enum HowSpecified { NotSpecified, Constant, Arg };
+
+ OptionalAmount(HowSpecified h, const char *st)
+ : start(st), hs(h), amt(0) {}
+
+ OptionalAmount()
+ : start(0), hs(NotSpecified), amt(0) {}
+
+ OptionalAmount(unsigned i, const char *st)
+ : start(st), hs(Constant), amt(i) {}
+
+ HowSpecified getHowSpecified() const { return hs; }
+ bool hasDataArgument() const { return hs == Arg; }
+
+ unsigned getConstantAmount() const {
+ assert(hs == Constant);
+ return amt;
+ }
+
+ const char *getStart() const {
+ return start;
+ }
+
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+private:
+ const char *start;
+ HowSpecified hs;
+ unsigned amt;
+};
+
+class FormatSpecifier {
+ LengthModifier LM;
+ unsigned IsLeftJustified : 1;
+ unsigned HasPlusPrefix : 1;
+ unsigned HasSpacePrefix : 1;
+ unsigned HasAlternativeForm : 1;
+ unsigned HasLeadingZeroes : 1;
+ unsigned flags : 5;
+ ConversionSpecifier CS;
+ OptionalAmount FieldWidth;
+ OptionalAmount Precision;
+public:
+ FormatSpecifier() : LM(None),
+ IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
+ HasAlternativeForm(0), HasLeadingZeroes(0) {}
+
+ static FormatSpecifier Parse(const char *beg, const char *end);
+
+ // Methods for incrementally constructing the FormatSpecifier.
+ void setConversionSpecifier(const ConversionSpecifier &cs) {
+ CS = cs;
+ }
+ void setLengthModifier(LengthModifier lm) {
+ LM = lm;
+ }
+ void setIsLeftJustified() { IsLeftJustified = 1; }
+ void setHasPlusPrefix() { HasPlusPrefix = 1; }
+ void setHasSpacePrefix() { HasSpacePrefix = 1; }
+ void setHasAlternativeForm() { HasAlternativeForm = 1; }
+ void setHasLeadingZeros() { HasLeadingZeroes = 1; }
+
+ // Methods for querying the format specifier.
+
+ const ConversionSpecifier &getConversionSpecifier() const {
+ return CS;
+ }
+
+ LengthModifier getLengthModifier() const {
+ return LM;
+ }
+
+ const OptionalAmount &getFieldWidth() const {
+ return FieldWidth;
+ }
+
+ void setFieldWidth(const OptionalAmount &Amt) {
+ FieldWidth = Amt;
+ }
+
+ void setPrecision(const OptionalAmount &Amt) {
+ Precision = Amt;
+ }
+
+ const OptionalAmount &getPrecision() const {
+ return Precision;
+ }
+
+ /// \brief Returns the builtin type that a data argument
+ /// paired with this format specifier should have. This method
+ /// will return null if the format specifier does not have
+ /// a matching data argument or the matching argument matches
+ /// more than one type.
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
+
+ bool isLeftJustified() const { return (bool) IsLeftJustified; }
+ bool hasPlusPrefix() const { return (bool) HasPlusPrefix; }
+ bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
+ bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
+ bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
+};
+
+class FormatStringHandler {
+public:
+ FormatStringHandler() {}
+ virtual ~FormatStringHandler();
+
+ virtual void HandleIncompleteFormatSpecifier(const char *startSpecifier,
+ unsigned specifierLen) {}
+
+ virtual void HandleNullChar(const char *nullCharacter) {}
+
+ virtual void
+ HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {}
+
+ virtual bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {
+ return true;
+ }
+};
+
+bool ParseFormatString(FormatStringHandler &H,
+ const char *beg, const char *end);
+
+} // end printf namespace
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 2b367b7e37f6..cd771acb06a5 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -70,5 +70,8 @@ public:
void InitializeValues(const CFG& cfg);
};
+
+void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
+ bool FullUninitTaint=false);
} // end namespace clang
#endif
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index c82bb962fd18..ea4f5b20669c 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -32,7 +32,6 @@ class LiveVariables;
class ParentMap;
class ImplicitParamDecl;
class LocationContextManager;
-class BlockDataRegion;
class StackFrameContext;
/// AnalysisContext contains the context data for the function or method under
@@ -207,35 +206,23 @@ public:
};
class BlockInvocationContext : public LocationContext {
- llvm::PointerUnion<const BlockDataRegion *, const BlockDecl *> Data;
+ // FIXME: Add back context-sensivity (we don't want libAnalysis to know
+ // about MemRegion).
+ const BlockDecl *BD;
friend class LocationContextManager;
BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
- const BlockDataRegion *br)
- : LocationContext(Block, ctx, parent), Data(br) {}
-
- BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
const BlockDecl *bd)
- : LocationContext(Block, ctx, parent), Data(bd) {}
+ : LocationContext(Block, ctx, parent), BD(bd) {}
public:
~BlockInvocationContext() {}
-
- const BlockDataRegion *getBlockRegion() const {
- return Data.is<const BlockDataRegion*>() ?
- Data.get<const BlockDataRegion*>() : 0;
- }
-
- const BlockDecl *getBlockDecl() const;
-
+
+ const BlockDecl *getBlockDecl() const { return BD; }
+
void Profile(llvm::FoldingSetNodeID &ID);
-
- static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const BlockDataRegion *br){
- ProfileCommon(ID, Block, ctx, parent, br);
- }
-
+
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
const LocationContext *parent, const BlockDecl *bd) {
ProfileCommon(ID, Block, ctx, parent, bd);
@@ -260,10 +247,6 @@ public:
const LocationContext *parent,
const Stmt *s);
- const BlockInvocationContext *
- getBlockInvocation(AnalysisContext *ctx, const LocationContext *parent,
- const BlockDataRegion *BR);
-
/// Discard all previously created LocationContext objects.
void clear();
private:
diff --git a/include/clang/Analysis/LocalCheckers.h b/include/clang/Analysis/LocalCheckers.h
deleted file mode 100644
index 9c343e078641..000000000000
--- a/include/clang/Analysis/LocalCheckers.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface to call a set of intra-procedural (local)
-// checkers that use flow/path-sensitive analyses to find bugs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
-#define LLVM_CLANG_ANALYSIS_LOCALCHECKERS_H
-
-namespace clang {
-
-class CFG;
-class Decl;
-class Diagnostic;
-class ASTContext;
-class PathDiagnosticClient;
-class GRTransferFuncs;
-class BugType;
-class LangOptions;
-class ParentMap;
-class LiveVariables;
-class BugReporter;
-class ObjCImplementationDecl;
-class LangOptions;
-class GRExprEngine;
-
-void CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &map,
- BugReporter& BR);
-
-void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
- bool FullUninitTaint=false);
-
-GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
- const LangOptions& lopts);
-
-void CheckObjCDealloc(const ObjCImplementationDecl* D, const LangOptions& L,
- BugReporter& BR);
-
-void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
- BugReporter& BR);
-
-void CheckObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter& BR);
-
-void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
-void RegisterExperimentalChecks(GRExprEngine &Eng);
-void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
-
-void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
-
-void CheckSizeofPointer(const Decl *D, BugReporter &BR);
-
-void RegisterCallInliner(GRExprEngine &Eng);
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Analysis/ManagerRegistry.h b/include/clang/Analysis/ManagerRegistry.h
deleted file mode 100644
index 972993855c28..000000000000
--- a/include/clang/Analysis/ManagerRegistry.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ManagerRegistry and Register* classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
-#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
-
-#include "clang/Analysis/PathSensitive/GRState.h"
-
-namespace clang {
-
-/// ManagerRegistry - This class records manager creators registered at
-/// runtime. The information is communicated to AnalysisManager through static
-/// members. Better design is expected.
-
-class ManagerRegistry {
-public:
- static StoreManagerCreator StoreMgrCreator;
- static ConstraintManagerCreator ConstraintMgrCreator;
-};
-
-/// RegisterConstraintManager - This class is used to setup the constraint
-/// manager of the static analyzer. The constructor takes a creator function
-/// pointer for creating the constraint manager.
-///
-/// It is used like this:
-///
-/// class MyConstraintManager {};
-/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
-/// return new MyConstraintManager(statemgr);
-/// }
-/// RegisterConstraintManager X(CreateMyConstraintManager);
-
-class RegisterConstraintManager {
-public:
- RegisterConstraintManager(ConstraintManagerCreator CMC) {
- assert(ManagerRegistry::ConstraintMgrCreator == 0
- && "ConstraintMgrCreator already set!");
- ManagerRegistry::ConstraintMgrCreator = CMC;
- }
-};
-
-}
-#endif
diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h
deleted file mode 100644
index d380c45480cb..000000000000
--- a/include/clang/Analysis/PathDiagnostic.h
+++ /dev/null
@@ -1,494 +0,0 @@
-//===--- PathDiagnostic.h - Path-Specific Diagnostic Handling ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the PathDiagnostic-related interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
-#define LLVM_CLANG_PATH_DIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/FoldingSet.h"
-#include <deque>
-#include <iterator>
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class Decl;
-class SourceManager;
-class Stmt;
-
-//===----------------------------------------------------------------------===//
-// High-level interface for handlers of path-sensitive diagnostics.
-//===----------------------------------------------------------------------===//
-
-class PathDiagnostic;
-
-class PathDiagnosticClient : public DiagnosticClient {
-public:
- PathDiagnosticClient() {}
-
- virtual ~PathDiagnosticClient() {}
-
- virtual void
- FlushDiagnostics(llvm::SmallVectorImpl<std::string> *FilesMade = 0) = 0;
-
- void FlushDiagnostics(llvm::SmallVectorImpl<std::string> &FilesMade) {
- FlushDiagnostics(&FilesMade);
- }
-
- virtual llvm::StringRef getName() const = 0;
-
- virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
- const DiagnosticInfo &Info);
- virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
-
- enum PathGenerationScheme { Minimal, Extensive };
- virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
- virtual bool supportsLogicalOpControlFlow() const { return false; }
- virtual bool supportsAllBlockEdges() const { return false; }
- virtual bool useVerboseDescription() const { return true; }
-};
-
-//===----------------------------------------------------------------------===//
-// Path-sensitive diagnostics.
-//===----------------------------------------------------------------------===//
-
-class PathDiagnosticRange : public SourceRange {
-public:
- const bool isPoint;
-
- PathDiagnosticRange(const SourceRange &R, bool isP = false)
- : SourceRange(R), isPoint(isP) {}
-};
-
-class PathDiagnosticLocation {
-private:
- enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
- SourceRange R;
- const Stmt *S;
- const Decl *D;
- const SourceManager *SM;
-public:
- PathDiagnosticLocation()
- : K(SingleLocK), S(0), D(0), SM(0) {}
-
- PathDiagnosticLocation(FullSourceLoc L)
- : K(SingleLocK), R(L, L), S(0), D(0), SM(&L.getManager()) {}
-
- PathDiagnosticLocation(const Stmt *s, const SourceManager &sm)
- : K(StmtK), S(s), D(0), SM(&sm) {}
-
- PathDiagnosticLocation(SourceRange r, const SourceManager &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 && D == X.D;
- }
-
- bool operator!=(const PathDiagnosticLocation &X) const {
- 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;
- }
-
- bool isValid() const {
- return SM != 0;
- }
-
- const SourceManager& getSourceManager() const { assert(isValid());return *SM;}
-
- FullSourceLoc asLocation() const;
- PathDiagnosticRange asRange() const;
- const Stmt *asStmt() const { assert(isValid()); return S; }
- const Decl *asDecl() const { assert(isValid()); return D; }
-
- bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
-
- void invalidate() {
- *this = PathDiagnosticLocation();
- }
-
- void flatten();
-
- const SourceManager& getManager() const { assert(isValid()); return *SM; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-};
-
-class PathDiagnosticLocationPair {
-private:
- PathDiagnosticLocation Start, End;
-public:
- PathDiagnosticLocationPair(const PathDiagnosticLocation &start,
- const PathDiagnosticLocation &end)
- : Start(start), End(end) {}
-
- const PathDiagnosticLocation &getStart() const { return Start; }
- const PathDiagnosticLocation &getEnd() const { return End; }
-
- void flatten() {
- Start.flatten();
- End.flatten();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Start.Profile(ID);
- End.Profile(ID);
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Path "pieces" for path-sensitive diagnostics.
-//===----------------------------------------------------------------------===//
-
-class PathDiagnosticPiece {
-public:
- enum Kind { ControlFlow, Event, Macro };
- enum DisplayHint { Above, Below };
-
-private:
- const std::string str;
- std::vector<CodeModificationHint> CodeModificationHints;
- const Kind kind;
- const DisplayHint Hint;
- std::vector<SourceRange> ranges;
-
- // Do not implement:
- PathDiagnosticPiece();
- PathDiagnosticPiece(const PathDiagnosticPiece &P);
- PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P);
-
-protected:
- PathDiagnosticPiece(llvm::StringRef s, Kind k, DisplayHint hint = Below);
-
- PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
-
-public:
- virtual ~PathDiagnosticPiece();
-
- const std::string& getString() const { return str; }
-
- /// getDisplayHint - Return a hint indicating where the diagnostic should
- /// be displayed by the PathDiagnosticClient.
- DisplayHint getDisplayHint() const { return Hint; }
-
- virtual PathDiagnosticLocation getLocation() const = 0;
- virtual void flattenLocations() = 0;
-
- Kind getKind() const { return kind; }
-
- void addRange(SourceRange R) { ranges.push_back(R); }
-
- void addRange(SourceLocation B, SourceLocation E) {
- ranges.push_back(SourceRange(B,E));
- }
-
- void addCodeModificationHint(const CodeModificationHint& Hint) {
- CodeModificationHints.push_back(Hint);
- }
-
- typedef const SourceRange* range_iterator;
-
- range_iterator ranges_begin() const {
- return ranges.empty() ? NULL : &ranges[0];
- }
-
- range_iterator ranges_end() const {
- return ranges_begin() + ranges.size();
- }
-
- typedef const CodeModificationHint *code_modifications_iterator;
-
- code_modifications_iterator code_modifications_begin() const {
- return CodeModificationHints.empty()? 0 : &CodeModificationHints[0];
- }
-
- code_modifications_iterator code_modifications_end() const {
- return CodeModificationHints.empty()? 0
- : &CodeModificationHints[0] + CodeModificationHints.size();
- }
-
- static inline bool classof(const PathDiagnosticPiece* P) {
- return true;
- }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
-};
-
-class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
-private:
- PathDiagnosticLocation Pos;
-public:
- PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos,
- llvm::StringRef s,
- PathDiagnosticPiece::Kind k,
- bool addPosRange = true)
- : PathDiagnosticPiece(s, k), Pos(pos) {
- assert(Pos.asLocation().isValid() &&
- "PathDiagnosticSpotPiece's must have a valid location.");
- if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
- }
-
- PathDiagnosticLocation getLocation() const { return Pos; }
- virtual void flattenLocations() { Pos.flatten(); }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
-};
-
-class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
-
-public:
- PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
- llvm::StringRef s, bool addPosRange = true)
- : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
-
- ~PathDiagnosticEventPiece();
-
- static inline bool classof(const PathDiagnosticPiece* P) {
- return P->getKind() == Event;
- }
-};
-
-class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
- std::vector<PathDiagnosticLocationPair> LPairs;
-public:
- PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
- const PathDiagnosticLocation &endPos,
- llvm::StringRef s)
- : PathDiagnosticPiece(s, ControlFlow) {
- LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
- }
-
- PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
- const PathDiagnosticLocation &endPos)
- : PathDiagnosticPiece(ControlFlow) {
- LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
- }
-
- ~PathDiagnosticControlFlowPiece();
-
- PathDiagnosticLocation getStartLocation() const {
- assert(!LPairs.empty() &&
- "PathDiagnosticControlFlowPiece needs at least one location.");
- return LPairs[0].getStart();
- }
-
- PathDiagnosticLocation getEndLocation() const {
- assert(!LPairs.empty() &&
- "PathDiagnosticControlFlowPiece needs at least one location.");
- return LPairs[0].getEnd();
- }
-
- void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
-
- virtual PathDiagnosticLocation getLocation() const {
- return getStartLocation();
- }
-
- typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
- iterator begin() { return LPairs.begin(); }
- iterator end() { return LPairs.end(); }
-
- virtual void flattenLocations() {
- for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
- }
-
- typedef std::vector<PathDiagnosticLocationPair>::const_iterator
- const_iterator;
- const_iterator begin() const { return LPairs.begin(); }
- const_iterator end() const { return LPairs.end(); }
-
- static inline bool classof(const PathDiagnosticPiece* P) {
- return P->getKind() == ControlFlow;
- }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
-};
-
-class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
- std::vector<PathDiagnosticPiece*> SubPieces;
-public:
- PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
- : PathDiagnosticSpotPiece(pos, "", Macro) {}
-
- ~PathDiagnosticMacroPiece();
-
- bool containsEvent() const;
-
- void push_back(PathDiagnosticPiece* P) { SubPieces.push_back(P); }
-
- typedef std::vector<PathDiagnosticPiece*>::iterator iterator;
- iterator begin() { return SubPieces.begin(); }
- iterator end() { return SubPieces.end(); }
-
- virtual void flattenLocations() {
- PathDiagnosticSpotPiece::flattenLocations();
- for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
- }
-
- typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
- const_iterator begin() const { return SubPieces.begin(); }
- const_iterator end() const { return SubPieces.end(); }
-
- static inline bool classof(const PathDiagnosticPiece* P) {
- return P->getKind() == Macro;
- }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) const;
-};
-
-/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
-/// diagnostic. It represents an ordered-collection of PathDiagnosticPieces,
-/// each which represent the pieces of the path.
-class PathDiagnostic : public llvm::FoldingSetNode {
- std::deque<PathDiagnosticPiece*> path;
- unsigned Size;
- std::string BugType;
- std::string Desc;
- std::string Category;
- std::deque<std::string> OtherDesc;
-
-public:
- PathDiagnostic();
-
- PathDiagnostic(llvm::StringRef bugtype, llvm::StringRef desc,
- llvm::StringRef category);
-
- ~PathDiagnostic();
-
- llvm::StringRef getDescription() const { return Desc; }
- llvm::StringRef getBugType() const { return BugType; }
- llvm::StringRef getCategory() const { return Category; }
-
- typedef std::deque<std::string>::const_iterator meta_iterator;
- meta_iterator meta_begin() const { return OtherDesc.begin(); }
- meta_iterator meta_end() const { return OtherDesc.end(); }
- void addMeta(llvm::StringRef s) { OtherDesc.push_back(s); }
-
- PathDiagnosticLocation getLocation() const {
- assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
- return rbegin()->getLocation();
- }
-
- void push_front(PathDiagnosticPiece* piece) {
- assert(piece);
- path.push_front(piece);
- ++Size;
- }
-
- void push_back(PathDiagnosticPiece* piece) {
- assert(piece);
- path.push_back(piece);
- ++Size;
- }
-
- PathDiagnosticPiece* back() {
- return path.back();
- }
-
- const PathDiagnosticPiece* back() const {
- return path.back();
- }
-
- unsigned size() const { return Size; }
- bool empty() const { return Size == 0; }
-
- void resetPath(bool deletePieces = true);
-
- class iterator {
- public:
- typedef std::deque<PathDiagnosticPiece*>::iterator ImplTy;
-
- typedef PathDiagnosticPiece value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- private:
- ImplTy I;
-
- public:
- iterator(const ImplTy& i) : I(i) {}
-
- bool operator==(const iterator& X) const { return I == X.I; }
- bool operator!=(const iterator& X) const { return I != X.I; }
-
- PathDiagnosticPiece& operator*() const { return **I; }
- PathDiagnosticPiece* operator->() const { return *I; }
-
- iterator& operator++() { ++I; return *this; }
- iterator& operator--() { --I; return *this; }
- };
-
- class const_iterator {
- public:
- typedef std::deque<PathDiagnosticPiece*>::const_iterator ImplTy;
-
- typedef const PathDiagnosticPiece value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
-
- private:
- ImplTy I;
-
- public:
- const_iterator(const ImplTy& i) : I(i) {}
-
- bool operator==(const const_iterator& X) const { return I == X.I; }
- bool operator!=(const const_iterator& X) const { return I != X.I; }
-
- reference operator*() const { return **I; }
- pointer operator->() const { return *I; }
-
- const_iterator& operator++() { ++I; return *this; }
- const_iterator& operator--() { --I; return *this; }
- };
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- // forward iterator creation methods.
-
- iterator begin() { return path.begin(); }
- iterator end() { return path.end(); }
-
- const_iterator begin() const { return path.begin(); }
- const_iterator end() const { return path.end(); }
-
- // reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-
- void flattenLocations() {
- for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-};
-} //end clang namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h
deleted file mode 100644
index 8288864f2b61..000000000000
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the AnalysisManager class that manages the data and policy
-// for path sensitive analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
-#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
-
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/AnalysisContext.h"
-#include "clang/Analysis/PathDiagnostic.h"
-
-namespace clang {
-
-class AnalysisManager : public BugReporterData {
- AnalysisContextManager AnaCtxMgr;
- LocationContextManager LocCtxMgr;
-
- ASTContext &Ctx;
- Diagnostic &Diags;
- const LangOptions &LangInfo;
-
- llvm::OwningPtr<PathDiagnosticClient> PD;
-
- // Configurable components creators.
- StoreManagerCreator CreateStoreMgr;
- ConstraintManagerCreator CreateConstraintMgr;
-
- enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
-
- bool VisualizeEGDot;
- bool VisualizeEGUbi;
- bool PurgeDead;
-
- /// EargerlyAssume - A flag indicating how the engine should handle
- // expressions such as: 'x = (y != 0)'. When this flag is true then
- // the subexpression 'y != 0' will be eagerly assumed to be true or false,
- // thus evaluating it to the integers 0 or 1 respectively. The upside
- // is that this can increase analysis precision until we have a better way
- // to lazily evaluate such logic. The downside is that it eagerly
- // bifurcates paths.
- bool EagerlyAssume;
- bool TrimGraph;
-
-public:
- AnalysisManager(ASTContext &ctx, Diagnostic &diags,
- const LangOptions &lang, PathDiagnosticClient *pd,
- StoreManagerCreator storemgr,
- ConstraintManagerCreator constraintmgr,
- bool vizdot, bool vizubi, bool purge, bool eager, bool trim)
-
- : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
- CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
- AScope(ScopeDecl),
- VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
- EagerlyAssume(eager), TrimGraph(trim) {}
-
- ~AnalysisManager() { FlushDiagnostics(); }
-
- void ClearContexts() {
- LocCtxMgr.clear();
- AnaCtxMgr.clear();
- }
-
- StoreManagerCreator getStoreManagerCreator() {
- return CreateStoreMgr;
- }
-
- ConstraintManagerCreator getConstraintManagerCreator() {
- return CreateConstraintMgr;
- }
-
- virtual ASTContext &getASTContext() {
- return Ctx;
- }
-
- virtual SourceManager &getSourceManager() {
- return getASTContext().getSourceManager();
- }
-
- virtual Diagnostic &getDiagnostic() {
- return Diags;
- }
-
- const LangOptions &getLangOptions() const {
- return LangInfo;
- }
-
- virtual PathDiagnosticClient *getPathDiagnosticClient() {
- return PD.get();
- }
-
- void FlushDiagnostics() {
- if (PD.get())
- PD->FlushDiagnostics();
- }
-
- bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
-
- bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
-
- bool shouldVisualize() const {
- return VisualizeEGDot || VisualizeEGUbi;
- }
-
- bool shouldTrimGraph() const { return TrimGraph; }
-
- bool shouldPurgeDead() const { return PurgeDead; }
-
- bool shouldEagerlyAssume() const { return EagerlyAssume; }
-
- CFG *getCFG(Decl const *D) {
- return AnaCtxMgr.getContext(D)->getCFG();
- }
-
- LiveVariables *getLiveVariables(Decl const *D) {
- return AnaCtxMgr.getContext(D)->getLiveVariables();
- }
-
- ParentMap &getParentMap(Decl const *D) {
- return AnaCtxMgr.getContext(D)->getParentMap();
- }
-
- // Get the top level stack frame.
- const StackFrameContext *getStackFrame(Decl const *D) {
- return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0);
- }
-
- // Get a stack frame with parent.
- StackFrameContext const *getStackFrame(Decl const *D,
- LocationContext const *Parent,
- Stmt const *S, const CFGBlock *Blk,
- unsigned Idx) {
- return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx);
- }
-};
-
-}
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/include/clang/Analysis/PathSensitive/BasicValueFactory.h
deleted file mode 100644
index 12f0ce2d50b7..000000000000
--- a/include/clang/Analysis/PathSensitive/BasicValueFactory.h
+++ /dev/null
@@ -1,198 +0,0 @@
-//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines BasicValueFactory, a class that manages the lifetime
-// of APSInt objects and symbolic constraints used by GRExprEngine
-// and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
-#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
-
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/ImmutableList.h"
-
-namespace clang {
-
- class GRState;
-
-class CompoundValData : public llvm::FoldingSetNode {
- QualType T;
- llvm::ImmutableList<SVal> L;
-
-public:
- CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
- : T(t), L(l) {}
-
- typedef llvm::ImmutableList<SVal>::iterator iterator;
- iterator begin() const { return L.begin(); }
- iterator end() const { return L.end(); }
-
- static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
- llvm::ImmutableList<SVal> L);
-
- void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
-};
-
-class LazyCompoundValData : public llvm::FoldingSetNode {
- const GRState *state;
- const TypedRegion *region;
-public:
- LazyCompoundValData(const GRState *st, const TypedRegion *r)
- : state(st), region(r) {}
-
- const GRState *getState() const { return state; }
- const TypedRegion *getRegion() const { return region; }
-
- static void Profile(llvm::FoldingSetNodeID& ID, const GRState *state,
- const TypedRegion *region);
-
- void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, state, region); }
-};
-
-class BasicValueFactory {
- typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
- APSIntSetTy;
-
- ASTContext& Ctx;
- llvm::BumpPtrAllocator& BPAlloc;
-
- APSIntSetTy APSIntSet;
- void* PersistentSVals;
- void* PersistentSValPairs;
-
- llvm::ImmutableList<SVal>::Factory SValListFactory;
- llvm::FoldingSet<CompoundValData> CompoundValDataSet;
- llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
-
-public:
- BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
- : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
- SValListFactory(Alloc) {}
-
- ~BasicValueFactory();
-
- ASTContext& getContext() const { return Ctx; }
-
- const llvm::APSInt& getValue(const llvm::APSInt& X);
- const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
- const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
- const llvm::APSInt& getValue(uint64_t X, QualType T);
-
- /// Convert - Create a new persistent APSInt with the same value as 'From'
- /// but with the bitwidth and signedness of 'To'.
- const llvm::APSInt &Convert(const llvm::APSInt& To,
- const llvm::APSInt& From) {
-
- if (To.isUnsigned() == From.isUnsigned() &&
- To.getBitWidth() == From.getBitWidth())
- return From;
-
- return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned());
- }
-
- const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
- assert(T->isIntegerType() || Loc::IsLocType(T));
- unsigned bitwidth = Ctx.getTypeSize(T);
- bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
-
- if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth())
- return From;
-
- return getValue(From.getSExtValue(), bitwidth, isUnsigned);
- }
-
- const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {
- QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
- return getValue(X, T);
- }
-
- inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) {
- return getValue(llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned()));
- }
-
- inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) {
- return getValue(llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned()));
- }
-
- inline const llvm::APSInt& getMaxValue(QualType T) {
- assert(T->isIntegerType() || Loc::IsLocType(T));
- bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
- return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned));
- }
-
- inline const llvm::APSInt& getMinValue(QualType T) {
- assert(T->isIntegerType() || Loc::IsLocType(T));
- bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
- return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned));
- }
-
- inline const llvm::APSInt& Add1(const llvm::APSInt& V) {
- llvm::APSInt X = V;
- ++X;
- return getValue(X);
- }
-
- inline const llvm::APSInt& Sub1(const llvm::APSInt& V) {
- llvm::APSInt X = V;
- --X;
- return getValue(X);
- }
-
- inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) {
- return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
- }
-
- inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
- return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
- }
-
- inline const llvm::APSInt& getTruthValue(bool b, QualType T) {
- return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false);
- }
-
- inline const llvm::APSInt& getTruthValue(bool b) {
- return getTruthValue(b, Ctx.IntTy);
- }
-
- const CompoundValData *getCompoundValData(QualType T,
- llvm::ImmutableList<SVal> Vals);
-
- const LazyCompoundValData *getLazyCompoundValData(const GRState *state,
- const TypedRegion *region);
-
- llvm::ImmutableList<SVal> getEmptySValList() {
- return SValListFactory.GetEmptyList();
- }
-
- llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
- return SValListFactory.Add(X, L);
- }
-
- const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1,
- const llvm::APSInt& V2);
-
- const std::pair<SVal, uintptr_t>&
- getPersistentSValWithData(const SVal& V, uintptr_t Data);
-
- const std::pair<SVal, SVal>&
- getPersistentSValPair(const SVal& V1, const SVal& V2);
-
- const SVal* getPersistentSVal(SVal X);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
deleted file mode 100644
index 6f6681a3629b..000000000000
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ /dev/null
@@ -1,473 +0,0 @@
-//===--- BugReporter.h - Generate PathDiagnostics --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines BugReporter, a utility class for generating
-// PathDiagnostics for analyses based on GRState.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
-#define LLVM_CLANG_ANALYSIS_BUGREPORTER
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/BugType.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/ImmutableSet.h"
-#include <list>
-
-namespace clang {
-
-class PathDiagnostic;
-class PathDiagnosticPiece;
-class PathDiagnosticClient;
-class ASTContext;
-class Diagnostic;
-class BugReporter;
-class BugReporterContext;
-class GRExprEngine;
-class GRState;
-class Stmt;
-class BugType;
-class ParentMap;
-
-//===----------------------------------------------------------------------===//
-// Interface for individual bug reports.
-//===----------------------------------------------------------------------===//
-
-class BugReporterVisitor {
-public:
- virtual ~BugReporterVisitor();
- virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
- const ExplodedNode* PrevN,
- BugReporterContext& BRC) = 0;
-
- virtual bool isOwnedByReporterContext() { return true; }
-};
-
-// FIXME: Combine this with RangedBugReport and remove RangedBugReport.
-class BugReport : public BugReporterVisitor {
-protected:
- BugType& BT;
- std::string ShortDescription;
- std::string Description;
- const ExplodedNode *EndNode;
- SourceRange R;
-
-protected:
- friend class BugReporter;
- friend class BugReportEquivClass;
-
- virtual void Profile(llvm::FoldingSetNodeID& hash) const {
- hash.AddInteger(getLocation().getRawEncoding());
- }
-
-public:
- class NodeResolver {
- public:
- virtual ~NodeResolver() {}
- virtual const ExplodedNode*
- getOriginalNode(const ExplodedNode* N) = 0;
- };
-
- BugReport(BugType& bt, llvm::StringRef desc, const ExplodedNode *n)
- : BT(bt), Description(desc), EndNode(n) {}
-
- BugReport(BugType& bt, llvm::StringRef shortDesc, llvm::StringRef desc,
- const ExplodedNode *n)
- : BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
-
- virtual ~BugReport();
-
- virtual bool isOwnedByReporterContext() { return false; }
-
- const BugType& getBugType() const { return BT; }
- BugType& getBugType() { return BT; }
-
- // FIXME: Perhaps this should be moved into a subclass?
- const ExplodedNode* getEndNode() const { return EndNode; }
-
- // FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint
- // object.
- // FIXME: If we do need it, we can probably just make it private to
- // BugReporter.
- const Stmt* getStmt() const;
-
- const llvm::StringRef getDescription() const { return Description; }
-
- const llvm::StringRef getShortDescription() const {
- return ShortDescription.empty() ? Description : ShortDescription;
- }
-
- // FIXME: Is this needed?
- virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
- return std::make_pair((const char**)0,(const char**)0);
- }
-
- // FIXME: Perhaps move this into a subclass.
- virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
- const ExplodedNode* N);
-
- /// getLocation - Return the "definitive" location of the reported bug.
- /// While a bug can span an entire path, usually there is a specific
- /// location that can be used to identify where the key issue occured.
- /// This location is used by clients rendering diagnostics.
- virtual SourceLocation getLocation() const;
-
- /// getRanges - Returns the source ranges associated with this bug.
- virtual void getRanges(const SourceRange*& beg, const SourceRange*& end);
-
- virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
- const ExplodedNode* PrevN,
- BugReporterContext& BR);
-
- virtual void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode* N) {}
-};
-
-//===----------------------------------------------------------------------===//
-// BugTypes (collections of related reports).
-//===----------------------------------------------------------------------===//
-
-class BugReportEquivClass : public llvm::FoldingSetNode {
- // List of *owned* BugReport objects.
- std::list<BugReport*> Reports;
-
- friend class BugReporter;
- void AddReport(BugReport* R) { Reports.push_back(R); }
-public:
- BugReportEquivClass(BugReport* R) { Reports.push_back(R); }
- ~BugReportEquivClass();
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- assert(!Reports.empty());
- (*Reports.begin())->Profile(ID);
- }
-
- class iterator {
- std::list<BugReport*>::iterator impl;
- public:
- iterator(std::list<BugReport*>::iterator i) : impl(i) {}
- iterator& operator++() { ++impl; return *this; }
- bool operator==(const iterator& I) const { return I.impl == impl; }
- bool operator!=(const iterator& I) const { return I.impl != impl; }
- BugReport* operator*() const { return *impl; }
- BugReport* operator->() const { return *impl; }
- };
-
- class const_iterator {
- std::list<BugReport*>::const_iterator impl;
- public:
- const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {}
- const_iterator& operator++() { ++impl; return *this; }
- bool operator==(const const_iterator& I) const { return I.impl == impl; }
- bool operator!=(const const_iterator& I) const { return I.impl != impl; }
- const BugReport* operator*() const { return *impl; }
- const BugReport* operator->() const { return *impl; }
- };
-
- iterator begin() { return iterator(Reports.begin()); }
- iterator end() { return iterator(Reports.end()); }
-
- const_iterator begin() const { return const_iterator(Reports.begin()); }
- const_iterator end() const { return const_iterator(Reports.end()); }
-};
-
-
-//===----------------------------------------------------------------------===//
-// Specialized subclasses of BugReport.
-//===----------------------------------------------------------------------===//
-
-// FIXME: Collapse this with the default BugReport class.
-class RangedBugReport : public BugReport {
- std::vector<SourceRange> Ranges;
-public:
- RangedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
- : BugReport(D, description, n) {}
-
- RangedBugReport(BugType& D, llvm::StringRef shortDescription,
- llvm::StringRef description, ExplodedNode *n)
- : BugReport(D, shortDescription, description, n) {}
-
- ~RangedBugReport();
-
- // FIXME: Move this out of line.
- void addRange(SourceRange R) {
- assert(R.isValid());
- Ranges.push_back(R);
- }
-
- // FIXME: Move this out of line.
- void getRanges(const SourceRange*& beg, const SourceRange*& end) {
-
- if (Ranges.empty()) {
- beg = NULL;
- end = NULL;
- }
- else {
- beg = &Ranges[0];
- end = beg + Ranges.size();
- }
- }
-};
-
-class EnhancedBugReport : public RangedBugReport {
-public:
- typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
- const ExplodedNode *N);
-
-private:
- typedef std::vector<std::pair<VisitorCreator, const void*> > Creators;
- Creators creators;
-
-public:
- EnhancedBugReport(BugType& D, llvm::StringRef description, ExplodedNode *n)
- : RangedBugReport(D, description, n) {}
-
- EnhancedBugReport(BugType& D, llvm::StringRef shortDescription,
- llvm::StringRef description, ExplodedNode *n)
- : RangedBugReport(D, shortDescription, description, n) {}
-
- ~EnhancedBugReport() {}
-
- void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) {
- for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I)
- I->first(BRC, I->second, N);
- }
-
- void addVisitorCreator(VisitorCreator creator, const void *data) {
- creators.push_back(std::make_pair(creator, data));
- }
-};
-
-//===----------------------------------------------------------------------===//
-// BugReporter and friends.
-//===----------------------------------------------------------------------===//
-
-class BugReporterData {
-public:
- virtual ~BugReporterData();
- virtual Diagnostic& getDiagnostic() = 0;
- virtual PathDiagnosticClient* getPathDiagnosticClient() = 0;
- virtual ASTContext& getASTContext() = 0;
- virtual SourceManager& getSourceManager() = 0;
-};
-
-class BugReporter {
-public:
- enum Kind { BaseBRKind, GRBugReporterKind };
-
-private:
- typedef llvm::ImmutableSet<BugType*> BugTypesTy;
- BugTypesTy::Factory F;
- BugTypesTy BugTypes;
-
- const Kind kind;
- BugReporterData& D;
-
- void FlushReport(BugReportEquivClass& EQ);
-
-protected:
- BugReporter(BugReporterData& d, Kind k) : BugTypes(F.GetEmptySet()), kind(k), D(d) {}
-
-public:
- BugReporter(BugReporterData& d) : BugTypes(F.GetEmptySet()), kind(BaseBRKind), D(d) {}
- virtual ~BugReporter();
-
- void FlushReports();
-
- Kind getKind() const { return kind; }
-
- Diagnostic& getDiagnostic() {
- return D.getDiagnostic();
- }
-
- PathDiagnosticClient* getPathDiagnosticClient() {
- return D.getPathDiagnosticClient();
- }
-
- typedef BugTypesTy::iterator iterator;
- iterator begin() { return BugTypes.begin(); }
- iterator end() { return BugTypes.end(); }
-
- ASTContext& getContext() { return D.getASTContext(); }
-
- SourceManager& getSourceManager() { return D.getSourceManager(); }
-
- virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
- BugReportEquivClass& EQ) {}
-
- void Register(BugType *BT);
-
- void EmitReport(BugReport *R);
-
- void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
- SourceLocation Loc,
- SourceRange* RangeBeg, unsigned NumRanges);
-
- void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
- llvm::StringRef BugStr, SourceLocation Loc,
- SourceRange* RangeBeg, unsigned NumRanges);
-
-
- void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
- SourceLocation Loc) {
- EmitBasicReport(BugName, BugStr, Loc, 0, 0);
- }
-
- void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
- llvm::StringRef BugStr, SourceLocation Loc) {
- EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0);
- }
-
- void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
- SourceLocation Loc, SourceRange R) {
- EmitBasicReport(BugName, BugStr, Loc, &R, 1);
- }
-
- void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef Category,
- llvm::StringRef BugStr, SourceLocation Loc,
- SourceRange R) {
- EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1);
- }
-
- static bool classof(const BugReporter* R) { return true; }
-};
-
-// FIXME: Get rid of GRBugReporter. It's the wrong abstraction.
-class GRBugReporter : public BugReporter {
- GRExprEngine& Eng;
- llvm::SmallSet<SymbolRef, 10> NotableSymbols;
-public:
- GRBugReporter(BugReporterData& d, GRExprEngine& eng)
- : BugReporter(d, GRBugReporterKind), Eng(eng) {}
-
- virtual ~GRBugReporter();
-
- /// getEngine - Return the analysis engine used to analyze a given
- /// function or method.
- GRExprEngine &getEngine() { return Eng; }
-
- /// getGraph - Get the exploded graph created by the analysis engine
- /// for the analyzed method or function.
- ExplodedGraph &getGraph();
-
- /// getStateManager - Return the state manager used by the analysis
- /// engine.
- GRStateManager &getStateManager();
-
- virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
- BugReportEquivClass& R);
-
- void addNotableSymbol(SymbolRef Sym) {
- NotableSymbols.insert(Sym);
- }
-
- bool isNotable(SymbolRef Sym) const {
- return (bool) NotableSymbols.count(Sym);
- }
-
- /// classof - Used by isa<>, cast<>, and dyn_cast<>.
- static bool classof(const BugReporter* R) {
- return R->getKind() == GRBugReporterKind;
- }
-};
-
-class BugReporterContext {
- GRBugReporter &BR;
- std::vector<BugReporterVisitor*> Callbacks;
-public:
- BugReporterContext(GRBugReporter& br) : BR(br) {}
- virtual ~BugReporterContext();
-
- void addVisitor(BugReporterVisitor* visitor) {
- if (visitor) Callbacks.push_back(visitor);
- }
-
- typedef std::vector<BugReporterVisitor*>::iterator visitor_iterator;
- visitor_iterator visitor_begin() { return Callbacks.begin(); }
- visitor_iterator visitor_end() { return Callbacks.end(); }
-
- GRBugReporter& getBugReporter() { return BR; }
-
- ExplodedGraph &getGraph() { return BR.getGraph(); }
-
- void addNotableSymbol(SymbolRef Sym) {
- // FIXME: For now forward to GRBugReporter.
- BR.addNotableSymbol(Sym);
- }
-
- bool isNotable(SymbolRef Sym) const {
- // FIXME: For now forward to GRBugReporter.
- return BR.isNotable(Sym);
- }
-
- GRStateManager& getStateManager() {
- return BR.getStateManager();
- }
-
- ValueManager& getValueManager() {
- return getStateManager().getValueManager();
- }
-
- ASTContext& getASTContext() {
- return BR.getContext();
- }
-
- SourceManager& getSourceManager() {
- return BR.getSourceManager();
- }
-
- virtual BugReport::NodeResolver& getNodeResolver() = 0;
-};
-
-class DiagBugReport : public RangedBugReport {
- std::list<std::string> Strs;
- FullSourceLoc L;
-public:
- DiagBugReport(BugType& D, llvm::StringRef desc, FullSourceLoc l) :
- RangedBugReport(D, desc, 0), L(l) {}
-
- virtual ~DiagBugReport() {}
-
- // FIXME: Move out-of-line (virtual function).
- SourceLocation getLocation() const { return L; }
-
- void addString(llvm::StringRef s) { Strs.push_back(s); }
-
- typedef std::list<std::string>::const_iterator str_iterator;
- str_iterator str_begin() const { return Strs.begin(); }
- str_iterator str_end() const { return Strs.end(); }
-};
-
-//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-
-namespace bugreporter {
-
-const Stmt *GetDerefExpr(const ExplodedNode *N);
-const Stmt *GetReceiverExpr(const ExplodedNode *N);
-const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetCalleeExpr(const ExplodedNode *N);
-const Stmt *GetRetValExpr(const ExplodedNode *N);
-
-void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
- const ExplodedNode* N);
-
-} // end namespace clang::bugreporter
-
-//===----------------------------------------------------------------------===//
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h
deleted file mode 100644
index b75a8189e54c..000000000000
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===--- BugType.h - Bug Information Desciption ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines BugType, a class representing a bug type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
-#define LLVM_CLANG_ANALYSIS_BUGTYPE
-
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include <llvm/ADT/FoldingSet.h>
-#include <string>
-
-namespace clang {
-
-class BugReportEquivClass;
-class BugReporter;
-class BuiltinBugReport;
-class BugReporterContext;
-class ExplodedNode;
-class GRExprEngine;
-
-class BugType {
-private:
- const std::string Name;
- const std::string Category;
- llvm::FoldingSet<BugReportEquivClass> EQClasses;
- friend class BugReporter;
- bool SuppressonSink;
-public:
- BugType(llvm::StringRef name, llvm::StringRef cat)
- : Name(name), Category(cat), SuppressonSink(false) {}
- virtual ~BugType();
-
- // FIXME: Should these be made strings as well?
- llvm::StringRef getName() const { return Name; }
- llvm::StringRef getCategory() const { return Category; }
-
- /// isSuppressOnSink - Returns true if bug reports associated with this bug
- /// type should be suppressed if the end node of the report is post-dominated
- /// by a sink node.
- bool isSuppressOnSink() const { return SuppressonSink; }
- void setSuppressOnSink(bool x) { SuppressonSink = x; }
-
- virtual void FlushReports(BugReporter& BR);
-
- typedef llvm::FoldingSet<BugReportEquivClass>::iterator iterator;
- iterator begin() { return EQClasses.begin(); }
- iterator end() { return EQClasses.end(); }
-
- typedef llvm::FoldingSet<BugReportEquivClass>::const_iterator const_iterator;
- const_iterator begin() const { return EQClasses.begin(); }
- const_iterator end() const { return EQClasses.end(); }
-};
-
-class BuiltinBug : public BugType {
- const std::string desc;
-public:
- BuiltinBug(const char *name, const char *description)
- : BugType(name, "Logic error"), desc(description) {}
-
- BuiltinBug(const char *name)
- : BugType(name, "Logic error"), desc(name) {}
-
- llvm::StringRef getDescription() const { return desc; }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
deleted file mode 100644
index 924a8b11b098..000000000000
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ /dev/null
@@ -1,281 +0,0 @@
-//== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines Checker and CheckerVisitor, classes used for creating
-// domain-specific checks.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CHECKER
-#define LLVM_CLANG_ANALYSIS_CHECKER
-#include "clang/Analysis/Support/SaveAndRestore.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-
-//===----------------------------------------------------------------------===//
-// Checker interface.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
- class GRExprEngine;
-
-class CheckerContext {
- ExplodedNodeSet &Dst;
- GRStmtNodeBuilder &B;
- GRExprEngine &Eng;
- ExplodedNode *Pred;
- SaveAndRestore<bool> OldSink;
- SaveAndRestore<const void*> OldTag;
- SaveAndRestore<ProgramPoint::Kind> OldPointKind;
- SaveOr OldHasGen;
- const GRState *ST;
- const Stmt *statement;
- const unsigned size;
- bool DoneEvaluating; // FIXME: This is not a permanent API change.
-public:
- CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
- GRExprEngine &eng, ExplodedNode *pred,
- const void *tag, ProgramPoint::Kind K,
- const Stmt *stmt = 0, const GRState *st = 0)
- : Dst(dst), B(builder), Eng(eng), Pred(pred),
- OldSink(B.BuildSinks),
- OldTag(B.Tag, tag),
- OldPointKind(B.PointKind, K),
- OldHasGen(B.HasGeneratedNode),
- ST(st), statement(stmt), size(Dst.size()) {}
-
- ~CheckerContext();
-
- GRExprEngine &getEngine() {
- return Eng;
- }
-
- AnalysisManager &getAnalysisManager() {
- return Eng.getAnalysisManager();
- }
-
- ConstraintManager &getConstraintManager() {
- return Eng.getConstraintManager();
- }
-
- StoreManager &getStoreManager() {
- return Eng.getStoreManager();
- }
-
- ExplodedNodeSet &getNodeSet() { return Dst; }
- GRStmtNodeBuilder &getNodeBuilder() { return B; }
- ExplodedNode *&getPredecessor() { return Pred; }
- const GRState *getState() { return ST ? ST : B.GetState(Pred); }
-
- ASTContext &getASTContext() {
- return Eng.getContext();
- }
-
- BugReporter &getBugReporter() {
- return Eng.getBugReporter();
- }
-
- SourceManager &getSourceManager() {
- return getBugReporter().getSourceManager();
- }
-
- ValueManager &getValueManager() {
- return Eng.getValueManager();
- }
-
- SValuator &getSValuator() {
- return Eng.getSValuator();
- }
-
- ExplodedNode *GenerateNode(bool autoTransition = true) {
- assert(statement && "Only transitions with statements currently supported");
- ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
- if (N && autoTransition)
- Dst.Add(N);
- return N;
- }
-
- ExplodedNode *GenerateNode(const Stmt *stmt, const GRState *state,
- bool autoTransition = true) {
- assert(state);
- ExplodedNode *N = GenerateNodeImpl(stmt, state, false);
- if (N && autoTransition)
- addTransition(N);
- return N;
- }
-
- ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred,
- bool autoTransition = true) {
- assert(statement && "Only transitions with statements currently supported");
- ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false);
- if (N && autoTransition)
- addTransition(N);
- return N;
- }
-
- ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
- assert(statement && "Only transitions with statements currently supported");
- ExplodedNode *N = GenerateNodeImpl(statement, state, false);
- if (N && autoTransition)
- addTransition(N);
- return N;
- }
-
- ExplodedNode *GenerateSink(const Stmt *stmt, const GRState *state = 0) {
- return GenerateNodeImpl(stmt, state ? state : getState(), true);
- }
-
- ExplodedNode *GenerateSink(const GRState *state = 0) {
- assert(statement && "Only transitions with statements currently supported");
- return GenerateNodeImpl(statement, state ? state : getState(), true);
- }
-
- void addTransition(ExplodedNode *node) {
- Dst.Add(node);
- }
-
- void addTransition(const GRState *state) {
- assert(state);
- if (state != getState() || (ST && ST != B.GetState(Pred)))
- GenerateNode(state, true);
- else
- Dst.Add(Pred);
- }
-
- void EmitReport(BugReport *R) {
- Eng.getBugReporter().EmitReport(R);
- }
-
-private:
- ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
- bool markAsSink) {
- ExplodedNode *node = B.generateNode(stmt, state, Pred);
- if (markAsSink && node)
- node->markAsSink();
- return node;
- }
-
- ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
- ExplodedNode *pred, bool markAsSink) {
- ExplodedNode *node = B.generateNode(stmt, state, pred);
- if (markAsSink && node)
- node->markAsSink();
- return node;
- }
-};
-
-class Checker {
-private:
- friend class GRExprEngine;
-
- // FIXME: Remove the 'tag' option.
- void GR_Visit(ExplodedNodeSet &Dst,
- GRStmtNodeBuilder &Builder,
- GRExprEngine &Eng,
- const Stmt *S,
- ExplodedNode *Pred, void *tag, bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, S);
- if (isPrevisit)
- _PreVisit(C, S);
- else
- _PostVisit(C, S);
- }
-
- bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
- GRExprEngine &Eng, const ObjCMessageExpr *ME,
- ExplodedNode *Pred, const GRState *state, void *tag) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
- ME, state);
- return EvalNilReceiver(C, ME);
- }
-
- bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
- GRExprEngine &Eng, const CallExpr *CE,
- ExplodedNode *Pred, void *tag) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
- CE);
- return EvalCallExpr(C, CE);
- }
-
- // FIXME: Remove the 'tag' option.
- void GR_VisitBind(ExplodedNodeSet &Dst,
- GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
- const Stmt *AssignE,
- const Stmt *StoreE, ExplodedNode *Pred, void *tag,
- SVal location, SVal val,
- bool isPrevisit) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind, StoreE);
- assert(isPrevisit && "Only previsit supported for now.");
- PreVisitBind(C, AssignE, StoreE, location, val);
- }
-
- // FIXME: Remove the 'tag' option.
- void GR_VisitLocation(ExplodedNodeSet &Dst,
- GRStmtNodeBuilder &Builder,
- GRExprEngine &Eng,
- const Stmt *S,
- ExplodedNode *Pred, const GRState *state,
- SVal location,
- void *tag, bool isLoad) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- isLoad ? ProgramPoint::PreLoadKind :
- ProgramPoint::PreStoreKind, S, state);
- VisitLocation(C, S, location);
- }
-
- void GR_EvalDeadSymbols(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
- GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
- SymbolReaper &SymReaper, void *tag) {
- CheckerContext C(Dst, Builder, Eng, Pred, tag,
- ProgramPoint::PostPurgeDeadSymbolsKind, S);
- EvalDeadSymbols(C, S, SymReaper);
- }
-
-public:
- virtual ~Checker();
- virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
- virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
- virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
- virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
- const Stmt *StoreE, SVal location, SVal val) {}
- virtual void EvalDeadSymbols(CheckerContext &C, const Stmt *S,
- SymbolReaper &SymReaper) {}
- virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
- GRExprEngine &Eng) {}
-
- virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
- GRExprEngine &Eng,
- Stmt *Condition, void *tag) {}
-
- virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
- return false;
- }
-
- virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
- return false;
- }
-
- virtual const GRState *EvalAssume(const GRState *state, SVal Cond,
- bool Assumption) {
- return state;
- }
-};
-} // end clang namespace
-
-#endif
-
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
deleted file mode 100644
index 7ec27efe5199..000000000000
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.def
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- CheckerVisitor.def - Metadata for CheckerVisitor ----------------*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the AST nodes accepted by the CheckerVisitor class.
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef PREVISIT
-#define PREVISIT(NODE, FALLBACK)
-#endif
-
-#ifndef POSTVISIT
-#define POSTVISIT(NODE, FALLBACK)
-#endif
-
-PREVISIT(ArraySubscriptExpr, Stmt)
-PREVISIT(BinaryOperator, Stmt)
-PREVISIT(CallExpr, Stmt)
-PREVISIT(CastExpr, Stmt)
-PREVISIT(CXXOperatorCallExpr, CallExpr)
-PREVISIT(DeclStmt, Stmt)
-PREVISIT(ObjCMessageExpr, Stmt)
-PREVISIT(ReturnStmt, Stmt)
-
-POSTVISIT(BlockExpr, Stmt)
-POSTVISIT(BinaryOperator, Stmt)
-POSTVISIT(CallExpr, Stmt)
-POSTVISIT(CXXOperatorCallExpr, CallExpr)
-POSTVISIT(ObjCMessageExpr, Stmt)
-
-#undef PREVISIT
-#undef POSTVISIT
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Analysis/PathSensitive/CheckerVisitor.h
deleted file mode 100644
index 37ec8def50b3..000000000000
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.h
+++ /dev/null
@@ -1,101 +0,0 @@
-//== CheckerVisitor.h - Abstract visitor for checkers ------------*- C++ -*--=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines CheckerVisitor.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CHECKERVISITOR
-#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR
-#include "clang/Analysis/PathSensitive/Checker.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-// Checker visitor interface. Used by subclasses of Checker to specify their
-// own checker visitor logic.
-//===----------------------------------------------------------------------===//
-
-/// CheckerVisitor - This class implements a simple visitor for Stmt subclasses.
-/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
-template<typename ImplClass>
-class CheckerVisitor : public Checker {
-public:
- virtual void _PreVisit(CheckerContext &C, const Stmt *S) {
- PreVisit(C, S);
- }
-
- virtual void _PostVisit(CheckerContext &C, const Stmt *S) {
- PostVisit(C, S);
- }
-
- void PreVisit(CheckerContext &C, const Stmt *S) {
- switch (S->getStmtClass()) {
- default:
- assert(false && "Unsupport statement.");
- return;
-
- case Stmt::ImplicitCastExprClass:
- case Stmt::ExplicitCastExprClass:
- case Stmt::CStyleCastExprClass:
- static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
- static_cast<const CastExpr*>(S));
- break;
-
- case Stmt::CompoundAssignOperatorClass:
- static_cast<ImplClass*>(this)->PreVisitBinaryOperator(C,
- static_cast<const BinaryOperator*>(S));
- break;
-
-#define PREVISIT(NAME, FALLBACK) \
-case Stmt::NAME ## Class:\
-static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
-break;
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
- }
- }
-
- void PostVisit(CheckerContext &C, const Stmt *S) {
- switch (S->getStmtClass()) {
- default:
- assert(false && "Unsupport statement.");
- return;
- case Stmt::CompoundAssignOperatorClass:
- static_cast<ImplClass*>(this)->PostVisitBinaryOperator(C,
- static_cast<const BinaryOperator*>(S));
- break;
-
-#define POSTVISIT(NAME, FALLBACK) \
-case Stmt::NAME ## Class:\
-static_cast<ImplClass*>(this)->\
-PostVisit ## NAME(C,static_cast<const NAME*>(S));\
-break;
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
- }
- }
-
- void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
- void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
-
-#define PREVISIT(NAME, FALLBACK) \
-void PreVisit ## NAME(CheckerContext &C, const NAME* S) {\
- PreVisit ## FALLBACK(C, S);\
-}
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
-
-#define POSTVISIT(NAME, FALLBACK) \
-void PostVisit ## NAME(CheckerContext &C, const NAME* S) {\
- PostVisit ## FALLBACK(C, S);\
-}
-#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
-};
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
deleted file mode 100644
index a84183e7f27f..000000000000
--- a/include/clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//== NullDerefChecker.h - Null dereference checker --------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines NullDerefChecker and UndefDerefChecker, two builtin checks
-// in GRExprEngine that check for null and undefined pointers at loads
-// and stores.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_DEREFCHECKER
-#define LLVM_CLANG_DEREFCHECKER
-
-#include <utility>
-
-namespace clang {
-
-class GRExprEngine;
-class ExplodedNode;
-
-std::pair<ExplodedNode * const *, ExplodedNode * const *>
-GetImplicitNullDereferences(GRExprEngine &Eng);
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h
deleted file mode 100644
index c8292802ae9d..000000000000
--- a/include/clang/Analysis/PathSensitive/ConstraintManager.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the interface to manage constraints on symbolic values.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
-#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
-
-// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place.
-#include "clang/Analysis/PathSensitive/Store.h"
-
-namespace llvm {
-class APSInt;
-}
-
-namespace clang {
-
-class GRState;
-class GRStateManager;
-class GRSubEngine;
-class SVal;
-
-class ConstraintManager {
-public:
- virtual ~ConstraintManager();
- virtual const GRState *Assume(const GRState *state, DefinedSVal Cond,
- bool Assumption) = 0;
-
- virtual const GRState *AssumeInBound(const GRState *state, DefinedSVal Idx,
- DefinedSVal UpperBound, bool Assumption) = 0;
-
- std::pair<const GRState*, const GRState*> AssumeDual(const GRState *state,
- DefinedSVal Cond) {
- return std::make_pair(Assume(state, Cond, true),
- Assume(state, Cond, false));
- }
-
- virtual const llvm::APSInt* getSymVal(const GRState *state,
- SymbolRef sym) const = 0;
-
- virtual bool isEqual(const GRState *state, SymbolRef sym,
- const llvm::APSInt& V) const = 0;
-
- virtual const GRState *RemoveDeadBindings(const GRState *state,
- SymbolReaper& SymReaper) = 0;
-
- virtual void print(const GRState *state, llvm::raw_ostream& Out,
- const char* nl, const char *sep) = 0;
-
- virtual void EndPath(const GRState *state) {}
-
- /// canReasonAbout - Not all ConstraintManagers can accurately reason about
- /// all SVal values. This method returns true if the ConstraintManager can
- /// reasonably handle a given SVal value. This is typically queried by
- /// GRExprEngine to determine if the value should be replaced with a
- /// conjured symbolic value in order to recover some precision.
- virtual bool canReasonAbout(SVal X) const = 0;
-};
-
-ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr,
- GRSubEngine &subengine);
-ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr,
- GRSubEngine &subengine);
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Analysis/PathSensitive/Environment.h
deleted file mode 100644
index 6d5c5678e59b..000000000000
--- a/include/clang/Analysis/PathSensitive/Environment.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the Environment and EnvironmentManager classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
-#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H
-
-// For using typedefs in StoreManager. Should find a better place for these
-// typedefs.
-#include "clang/Analysis/PathSensitive/Store.h"
-
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/FoldingSet.h"
-
-namespace clang {
-
-class AnalysisContext;
-class EnvironmentManager;
-class ValueManager;
-class LiveVariables;
-
-
-class Environment {
-private:
- friend class EnvironmentManager;
-
- // Type definitions.
- typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy;
-
- // Data.
- BindingsTy ExprBindings;
- AnalysisContext *ACtx;
-
- Environment(BindingsTy eb, AnalysisContext *aCtx)
- : ExprBindings(eb), ACtx(aCtx) {}
-
-public:
- typedef BindingsTy::iterator iterator;
- iterator begin() const { return ExprBindings.begin(); }
- iterator end() const { return ExprBindings.end(); }
-
- SVal LookupExpr(const Stmt* E) const {
- const SVal* X = ExprBindings.lookup(E);
- return X ? *X : UnknownVal();
- }
-
- SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
-
- AnalysisContext &getAnalysisContext() const { return *ACtx; }
-
- /// Profile - Profile the contents of an Environment object for use
- /// in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
- E->ExprBindings.Profile(ID);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- bool operator==(const Environment& RHS) const {
- return ExprBindings == RHS.ExprBindings;
- }
-};
-
-class EnvironmentManager {
-private:
- typedef Environment::BindingsTy::Factory FactoryTy;
- FactoryTy F;
-
-public:
- EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
- ~EnvironmentManager() {}
-
- Environment getInitialEnvironment(AnalysisContext *ACtx) {
- return Environment(F.GetEmptyMap(), ACtx);
- }
-
- Environment BindExpr(Environment Env, const Stmt *S, SVal V,
- bool Invalidate);
-
- Environment RemoveDeadBindings(Environment Env, const Stmt *S,
- SymbolReaper &SymReaper, const GRState *ST,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h
deleted file mode 100644
index fb5e1b8a415f..000000000000
--- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h
+++ /dev/null
@@ -1,432 +0,0 @@
-//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the template classes ExplodedNode and ExplodedGraph,
-// which represent a path-sensitive, intra-procedural "exploded graph."
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
-#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
-
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/Analysis/PathSensitive/AnalysisContext.h"
-#include "clang/AST/Decl.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/Support/Casting.h"
-#include "clang/Analysis/Support/BumpVector.h"
-
-namespace clang {
-
-class GRState;
-class CFG;
-class ASTContext;
-class ExplodedGraph;
-
-//===----------------------------------------------------------------------===//
-// ExplodedGraph "implementation" classes. These classes are not typed to
-// contain a specific kind of state. Typed-specialized versions are defined
-// on top of these classes.
-//===----------------------------------------------------------------------===//
-
-class ExplodedNode : public llvm::FoldingSetNode {
- friend class ExplodedGraph;
- friend class GRCoreEngine;
- friend class GRStmtNodeBuilder;
- friend class GRBranchNodeBuilder;
- friend class GRIndirectGotoNodeBuilder;
- friend class GRSwitchNodeBuilder;
- friend class GREndPathNodeBuilder;
-
- class NodeGroup {
- enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 };
- uintptr_t P;
-
- unsigned getKind() const {
- return P & 0x1;
- }
-
- void* getPtr() const {
- assert (!getFlag());
- return reinterpret_cast<void*>(P & ~Mask);
- }
-
- ExplodedNode *getNode() const {
- return reinterpret_cast<ExplodedNode*>(getPtr());
- }
-
- public:
- NodeGroup() : P(0) {}
-
- ExplodedNode **begin() const;
-
- ExplodedNode **end() const;
-
- unsigned size() const;
-
- bool empty() const { return (P & ~Mask) == 0; }
-
- void addNode(ExplodedNode* N, ExplodedGraph &G);
-
- void setFlag() {
- assert(P == 0);
- P = AuxFlag;
- }
-
- bool getFlag() const {
- return P & AuxFlag ? true : false;
- }
- };
-
- /// Location - The program location (within a function body) associated
- /// with this node.
- const ProgramPoint Location;
-
- /// State - The state associated with this node.
- const GRState* State;
-
- /// Preds - The predecessors of this node.
- NodeGroup Preds;
-
- /// Succs - The successors of this node.
- NodeGroup Succs;
-
-public:
-
- explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
- : Location(loc), State(state) {}
-
- /// getLocation - Returns the edge associated with the given node.
- ProgramPoint getLocation() const { return Location; }
-
- const LocationContext *getLocationContext() const {
- return getLocation().getLocationContext();
- }
-
- const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
-
- CFG &getCFG() const { return *getLocationContext()->getCFG(); }
-
- ParentMap &getParentMap() const {return getLocationContext()->getParentMap();}
-
- LiveVariables &getLiveVariables() const {
- return *getLocationContext()->getLiveVariables();
- }
-
- const GRState* getState() const { return State; }
-
- template <typename T>
- const T* getLocationAs() const { return llvm::dyn_cast<T>(&Location); }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- const ProgramPoint& Loc, const GRState* state) {
- ID.Add(Loc);
- ID.AddPointer(state);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, getLocation(), getState());
- }
-
- /// addPredeccessor - Adds a predecessor to the current node, and
- /// in tandem add this node as a successor of the other node.
- void addPredecessor(ExplodedNode* V, ExplodedGraph &G);
-
- unsigned succ_size() const { return Succs.size(); }
- unsigned pred_size() const { return Preds.size(); }
- bool succ_empty() const { return Succs.empty(); }
- bool pred_empty() const { return Preds.empty(); }
-
- bool isSink() const { return Succs.getFlag(); }
- void markAsSink() { Succs.setFlag(); }
-
- ExplodedNode* getFirstPred() {
- return pred_empty() ? NULL : *(pred_begin());
- }
-
- const ExplodedNode* getFirstPred() const {
- return const_cast<ExplodedNode*>(this)->getFirstPred();
- }
-
- // Iterators over successor and predecessor vertices.
- typedef ExplodedNode** succ_iterator;
- typedef const ExplodedNode* const * const_succ_iterator;
- typedef ExplodedNode** pred_iterator;
- typedef const ExplodedNode* const * const_pred_iterator;
-
- pred_iterator pred_begin() { return Preds.begin(); }
- pred_iterator pred_end() { return Preds.end(); }
-
- const_pred_iterator pred_begin() const {
- return const_cast<ExplodedNode*>(this)->pred_begin();
- }
- const_pred_iterator pred_end() const {
- return const_cast<ExplodedNode*>(this)->pred_end();
- }
-
- succ_iterator succ_begin() { return Succs.begin(); }
- succ_iterator succ_end() { return Succs.end(); }
-
- const_succ_iterator succ_begin() const {
- return const_cast<ExplodedNode*>(this)->succ_begin();
- }
- const_succ_iterator succ_end() const {
- return const_cast<ExplodedNode*>(this)->succ_end();
- }
-
- // For debugging.
-
-public:
-
- class Auditor {
- public:
- virtual ~Auditor();
- virtual void AddEdge(ExplodedNode* Src, ExplodedNode* Dst) = 0;
- };
-
- static void SetAuditor(Auditor* A);
-};
-
-// FIXME: Is this class necessary?
-class InterExplodedGraphMap {
- llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
- friend class ExplodedGraph;
-
-public:
- ExplodedNode* getMappedNode(const ExplodedNode* N) const;
-
- InterExplodedGraphMap() {}
- virtual ~InterExplodedGraphMap() {}
-};
-
-class ExplodedGraph {
-protected:
- friend class GRCoreEngine;
-
- // Type definitions.
- typedef llvm::SmallVector<ExplodedNode*,2> RootsTy;
- typedef llvm::SmallVector<ExplodedNode*,10> EndNodesTy;
-
- /// Roots - The roots of the simulation graph. Usually there will be only
- /// one, but clients are free to establish multiple subgraphs within a single
- /// SimulGraph. Moreover, these subgraphs can often merge when paths from
- /// different roots reach the same state at the same program location.
- RootsTy Roots;
-
- /// EndNodes - The nodes in the simulation graph which have been
- /// specially marked as the endpoint of an abstract simulation path.
- EndNodesTy EndNodes;
-
- /// Nodes - The nodes in the graph.
- llvm::FoldingSet<ExplodedNode> Nodes;
-
- /// BVC - Allocator and context for allocating nodes and their predecessor
- /// and successor groups.
- BumpVectorContext BVC;
-
- /// Ctx - The ASTContext used to "interpret" CodeDecl.
- ASTContext& Ctx;
-
- /// NumNodes - The number of nodes in the graph.
- unsigned NumNodes;
-
-public:
- /// getNode - Retrieve the node associated with a (Location,State) pair,
- /// where the 'Location' is a ProgramPoint in the CFG. If no node for
- /// this pair exists, it is created. IsNew is set to true if
- /// the node was freshly created.
-
- ExplodedNode* getNode(const ProgramPoint& L, const GRState *State,
- bool* IsNew = 0);
-
- ExplodedGraph* MakeEmptyGraph() const {
- return new ExplodedGraph(Ctx);
- }
-
- /// addRoot - Add an untyped node to the set of roots.
- ExplodedNode* addRoot(ExplodedNode* V) {
- Roots.push_back(V);
- return V;
- }
-
- /// addEndOfPath - Add an untyped node to the set of EOP nodes.
- ExplodedNode* addEndOfPath(ExplodedNode* V) {
- EndNodes.push_back(V);
- return V;
- }
-
- ExplodedGraph(ASTContext& ctx) : Ctx(ctx), NumNodes(0) {}
-
- ~ExplodedGraph() {}
-
- unsigned num_roots() const { return Roots.size(); }
- unsigned num_eops() const { return EndNodes.size(); }
-
- bool empty() const { return NumNodes == 0; }
- unsigned size() const { return NumNodes; }
-
- // Iterators.
- typedef ExplodedNode NodeTy;
- typedef llvm::FoldingSet<ExplodedNode> AllNodesTy;
- typedef NodeTy** roots_iterator;
- typedef NodeTy* const * const_roots_iterator;
- typedef NodeTy** eop_iterator;
- typedef NodeTy* const * const_eop_iterator;
- typedef AllNodesTy::iterator node_iterator;
- typedef AllNodesTy::const_iterator const_node_iterator;
-
- node_iterator nodes_begin() { return Nodes.begin(); }
-
- node_iterator nodes_end() { return Nodes.end(); }
-
- const_node_iterator nodes_begin() const { return Nodes.begin(); }
-
- const_node_iterator nodes_end() const { return Nodes.end(); }
-
- roots_iterator roots_begin() { return Roots.begin(); }
-
- roots_iterator roots_end() { return Roots.end(); }
-
- const_roots_iterator roots_begin() const { return Roots.begin(); }
-
- const_roots_iterator roots_end() const { return Roots.end(); }
-
- eop_iterator eop_begin() { return EndNodes.begin(); }
-
- eop_iterator eop_end() { return EndNodes.end(); }
-
- const_eop_iterator eop_begin() const { return EndNodes.begin(); }
-
- const_eop_iterator eop_end() const { return EndNodes.end(); }
-
- llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
- BumpVectorContext &getNodeAllocator() { return BVC; }
-
- ASTContext& getContext() { return Ctx; }
-
- typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
-
- std::pair<ExplodedGraph*, InterExplodedGraphMap*>
- Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
- llvm::DenseMap<const void*, const void*> *InverseMap = 0) const;
-
- ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg,
- const ExplodedNode* const * NEnd,
- InterExplodedGraphMap *M,
- llvm::DenseMap<const void*, const void*> *InverseMap) const;
-};
-
-class ExplodedNodeSet {
- typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
- ImplTy Impl;
-
-public:
- ExplodedNodeSet(ExplodedNode* N) {
- assert (N && !static_cast<ExplodedNode*>(N)->isSink());
- Impl.insert(N);
- }
-
- ExplodedNodeSet() {}
-
- inline void Add(ExplodedNode* N) {
- if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
- }
-
- ExplodedNodeSet& operator=(const ExplodedNodeSet &X) {
- Impl = X.Impl;
- return *this;
- }
-
- typedef ImplTy::iterator iterator;
- typedef ImplTy::const_iterator const_iterator;
-
- unsigned size() const { return Impl.size(); }
- bool empty() const { return Impl.empty(); }
-
- void clear() { Impl.clear(); }
- void insert(const ExplodedNodeSet &S) {
- if (empty())
- Impl = S.Impl;
- else
- Impl.insert(S.begin(), S.end());
- }
-
- inline iterator begin() { return Impl.begin(); }
- inline iterator end() { return Impl.end(); }
-
- inline const_iterator begin() const { return Impl.begin(); }
- inline const_iterator end() const { return Impl.end(); }
-};
-
-} // end clang namespace
-
-// GraphTraits
-
-namespace llvm {
- template<> struct GraphTraits<clang::ExplodedNode*> {
- typedef clang::ExplodedNode NodeType;
- typedef NodeType::succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
-
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
-
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
-
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
- };
-
- template<> struct GraphTraits<const clang::ExplodedNode*> {
- typedef const clang::ExplodedNode NodeType;
- typedef NodeType::const_succ_iterator ChildIteratorType;
- typedef llvm::df_iterator<NodeType*> nodes_iterator;
-
- static inline NodeType* getEntryNode(NodeType* N) {
- return N;
- }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- return N->succ_begin();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- return N->succ_end();
- }
-
- static inline nodes_iterator nodes_begin(NodeType* N) {
- return df_begin(N);
- }
-
- static inline nodes_iterator nodes_end(NodeType* N) {
- return df_end(N);
- }
- };
-
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRAuditor.h b/include/clang/Analysis/PathSensitive/GRAuditor.h
deleted file mode 100644
index 015c82e80bb5..000000000000
--- a/include/clang/Analysis/PathSensitive/GRAuditor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//==- GRAuditor.h - Observers of the creation of ExplodedNodes------*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines GRAuditor and its primary subclasses, an interface
-// to audit the creation of ExplodedNodes. This interface can be used
-// to implement simple checkers that do not mutate analysis state but
-// instead operate by perfoming simple logical checks at key monitoring
-// locations (e.g., function calls).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRAUDITOR
-#define LLVM_CLANG_ANALYSIS_GRAUDITOR
-
-namespace clang {
-
-class ExplodedNode;
-class GRStateManager;
-
-class GRAuditor {
-public:
- virtual ~GRAuditor() {}
- virtual bool Audit(ExplodedNode* N, GRStateManager& M) = 0;
-};
-
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRBlockCounter.h b/include/clang/Analysis/PathSensitive/GRBlockCounter.h
deleted file mode 100644
index 67ed9532db02..000000000000
--- a/include/clang/Analysis/PathSensitive/GRBlockCounter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines GRBlockCounter, an abstract data type used to count
-// the number of times a given block has been visited along a path
-// analyzed by GRCoreEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
-#define LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
-
-namespace llvm {
- class BumpPtrAllocator;
-}
-
-namespace clang {
-
-class GRBlockCounter {
- void* Data;
-
- GRBlockCounter(void* D) : Data(D) {}
-
-public:
- GRBlockCounter() : Data(0) {}
-
- unsigned getNumVisited(unsigned BlockID) const;
-
- class Factory {
- void* F;
- public:
- Factory(llvm::BumpPtrAllocator& Alloc);
- ~Factory();
-
- GRBlockCounter GetEmptyCounter();
- GRBlockCounter IncrementCount(GRBlockCounter BC, unsigned BlockID);
- };
-
- friend class Factory;
-};
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
deleted file mode 100644
index 74f7a147b841..000000000000
--- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ /dev/null
@@ -1,443 +0,0 @@
-//==- GRCoreEngine.h - Path-Sensitive Dataflow Engine --------------*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a generic engine for intraprocedural, path-sensitive,
-// dataflow analysis via graph reachability.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRENGINE
-#define LLVM_CLANG_ANALYSIS_GRENGINE
-
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
-#include "clang/Analysis/PathSensitive/GRWorkList.h"
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
-#include "clang/Analysis/PathSensitive/GRAuditor.h"
-#include "clang/Analysis/PathSensitive/GRSubEngine.h"
-#include "llvm/ADT/OwningPtr.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-/// GRCoreEngine - Implements the core logic of the graph-reachability
-/// analysis. It traverses the CFG and generates the ExplodedGraph.
-/// Program "states" are treated as opaque void pointers.
-/// The template class GRCoreEngine (which subclasses GRCoreEngine)
-/// provides the matching component to the engine that knows the actual types
-/// for states. Note that this engine only dispatches to transfer functions
-/// at the statement and block-level. The analyses themselves must implement
-/// any transfer function logic and the sub-expression level (if any).
-class GRCoreEngine {
- friend class GRStmtNodeBuilder;
- friend class GRBranchNodeBuilder;
- friend class GRIndirectGotoNodeBuilder;
- friend class GRSwitchNodeBuilder;
- friend class GREndPathNodeBuilder;
-
- GRSubEngine& SubEngine;
-
- /// G - The simulation graph. Each node is a (location,state) pair.
- llvm::OwningPtr<ExplodedGraph> G;
-
- /// WList - A set of queued nodes that need to be processed by the
- /// worklist algorithm. It is up to the implementation of WList to decide
- /// the order that nodes are processed.
- GRWorkList* WList;
-
- /// BCounterFactory - A factory object for created GRBlockCounter objects.
- /// These are used to record for key nodes in the ExplodedGraph the
- /// number of times different CFGBlocks have been visited along a path.
- GRBlockCounter::Factory BCounterFactory;
-
- void GenerateNode(const ProgramPoint& Loc, const GRState* State,
- ExplodedNode* Pred);
-
- void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
- void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
- void HandleBlockExit(CFGBlock* B, ExplodedNode* Pred);
- void HandlePostStmt(const PostStmt& S, CFGBlock* B,
- unsigned StmtIdx, ExplodedNode *Pred);
-
- void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
- ExplodedNode* Pred);
-
- /// Get the initial state from the subengine.
- const GRState* getInitialState(const LocationContext *InitLoc) {
- return SubEngine.getInitialState(InitLoc);
- }
-
- void ProcessEndPath(GREndPathNodeBuilder& Builder);
-
- void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
-
- bool ProcessBlockEntrance(CFGBlock* Blk, const GRState* State,
- GRBlockCounter BC);
-
-
- void ProcessBranch(Stmt* Condition, Stmt* Terminator,
- GRBranchNodeBuilder& Builder);
-
-
- void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& Builder);
-
-
- void ProcessSwitch(GRSwitchNodeBuilder& Builder);
-
-private:
- GRCoreEngine(const GRCoreEngine&); // Do not implement.
- GRCoreEngine& operator=(const GRCoreEngine&);
-
-public:
- /// Construct a GRCoreEngine object to analyze the provided CFG using
- /// a DFS exploration of the exploded graph.
- GRCoreEngine(ASTContext& ctx, GRSubEngine& subengine)
- : SubEngine(subengine), G(new ExplodedGraph(ctx)),
- WList(GRWorkList::MakeBFS()),
- BCounterFactory(G->getAllocator()) {}
-
- /// Construct a GRCoreEngine object to analyze the provided CFG and to
- /// use the provided worklist object to execute the worklist algorithm.
- /// The GRCoreEngine object assumes ownership of 'wlist'.
- GRCoreEngine(ASTContext& ctx, GRWorkList* wlist, GRSubEngine& subengine)
- : SubEngine(subengine), G(new ExplodedGraph(ctx)), WList(wlist),
- BCounterFactory(G->getAllocator()) {}
-
- ~GRCoreEngine() {
- delete WList;
- }
-
- /// getGraph - Returns the exploded graph.
- ExplodedGraph& getGraph() { return *G.get(); }
-
- /// takeGraph - Returns the exploded graph. Ownership of the graph is
- /// transfered to the caller.
- ExplodedGraph* takeGraph() { return G.take(); }
-
- /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
- /// steps. Returns true if there is still simulation state on the worklist.
- bool ExecuteWorkList(const LocationContext *L, unsigned Steps);
-};
-
-class GRStmtNodeBuilder {
- GRCoreEngine& Eng;
- CFGBlock& B;
- const unsigned Idx;
- ExplodedNode* Pred;
- ExplodedNode* LastNode;
- GRStateManager& Mgr;
- GRAuditor* Auditor;
-
-public:
- bool PurgingDeadSymbols;
- bool BuildSinks;
- bool HasGeneratedNode;
- ProgramPoint::Kind PointKind;
- const void *Tag;
-
- const GRState* CleanedState;
-
-
- typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
- DeferredTy Deferred;
-
- void GenerateAutoTransition(ExplodedNode* N);
-
-public:
- GRStmtNodeBuilder(CFGBlock* b, unsigned idx, ExplodedNode* N,
- GRCoreEngine* e, GRStateManager &mgr);
-
- ~GRStmtNodeBuilder();
-
- ExplodedNode* getBasePredecessor() const { return Pred; }
-
- ExplodedNode* getLastNode() const {
- return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL;
- }
-
- // FIXME: This should not be exposed.
- GRWorkList *getWorkList() { return Eng.WList; }
-
- void SetCleanedState(const GRState* St) {
- CleanedState = St;
- }
-
- GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
-
- unsigned getCurrentBlockCount() const {
- return getBlockCounter().getNumVisited(B.getBlockID());
- }
-
- ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
- HasGeneratedNode = true;
- return generateNodeInternal(PP, St, Pred);
- }
-
- ExplodedNode* generateNode(const Stmt *S, const GRState *St,
- ExplodedNode *Pred, ProgramPoint::Kind K) {
- HasGeneratedNode = true;
-
- if (PurgingDeadSymbols)
- K = ProgramPoint::PostPurgeDeadSymbolsKind;
-
- return generateNodeInternal(S, St, Pred, K, Tag);
- }
-
- ExplodedNode* generateNode(const Stmt *S, const GRState *St,
- ExplodedNode *Pred) {
- return generateNode(S, St, Pred, PointKind);
- }
-
- ExplodedNode*
- generateNodeInternal(const ProgramPoint &PP, const GRState* State,
- ExplodedNode* Pred);
-
- ExplodedNode*
- generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
- const void *tag = 0);
-
- /// getStmt - Return the current block-level expression associated with
- /// this builder.
- Stmt* getStmt() const { return B[Idx]; }
-
- /// getBlock - Return the CFGBlock associated with the block-level expression
- /// of this builder.
- CFGBlock* getBlock() const { return &B; }
-
- unsigned getIndex() const { return Idx; }
-
- void setAuditor(GRAuditor* A) { Auditor = A; }
-
- const GRState* GetState(ExplodedNode* Pred) const {
- if (Pred == getBasePredecessor())
- return CleanedState;
- else
- return Pred->getState();
- }
-
- ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
- const GRState* St) {
- return MakeNode(Dst, S, Pred, St, PointKind);
- }
-
- ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
- const GRState* St, ProgramPoint::Kind K) {
-
- const GRState* PredState = GetState(Pred);
-
- // If the state hasn't changed, don't generate a new node.
- if (!BuildSinks && St == PredState && Auditor == 0) {
- Dst.Add(Pred);
- return NULL;
- }
-
- ExplodedNode* N = generateNode(S, St, Pred, K);
-
- if (N) {
- if (BuildSinks)
- N->markAsSink();
- else {
- if (Auditor && Auditor->Audit(N, Mgr))
- N->markAsSink();
-
- Dst.Add(N);
- }
- }
-
- return N;
- }
-
- ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S,
- ExplodedNode* Pred, const GRState* St) {
- bool Tmp = BuildSinks;
- BuildSinks = true;
- ExplodedNode* N = MakeNode(Dst, S, Pred, St);
- BuildSinks = Tmp;
- return N;
- }
-
-};
-
-class GRBranchNodeBuilder {
- GRCoreEngine& Eng;
- CFGBlock* Src;
- CFGBlock* DstT;
- CFGBlock* DstF;
- ExplodedNode* Pred;
-
- typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
- DeferredTy Deferred;
-
- bool GeneratedTrue;
- bool GeneratedFalse;
- bool InFeasibleTrue;
- bool InFeasibleFalse;
-
-public:
- GRBranchNodeBuilder(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
- ExplodedNode* pred, GRCoreEngine* e)
- : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
- GeneratedTrue(false), GeneratedFalse(false),
- InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
-
- ~GRBranchNodeBuilder();
-
- ExplodedNode* getPredecessor() const { return Pred; }
-
- const ExplodedGraph& getGraph() const { return *Eng.G; }
-
- GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
-
- ExplodedNode* generateNode(const GRState* State, bool branch);
-
- CFGBlock* getTargetBlock(bool branch) const {
- return branch ? DstT : DstF;
- }
-
- void markInfeasible(bool branch) {
- if (branch)
- InFeasibleTrue = GeneratedTrue = true;
- else
- InFeasibleFalse = GeneratedFalse = true;
- }
-
- bool isFeasible(bool branch) {
- return branch ? !InFeasibleTrue : !InFeasibleFalse;
- }
-
- const GRState* getState() const {
- return getPredecessor()->getState();
- }
-};
-
-class GRIndirectGotoNodeBuilder {
- GRCoreEngine& Eng;
- CFGBlock* Src;
- CFGBlock& DispatchBlock;
- Expr* E;
- ExplodedNode* Pred;
-
-public:
- GRIndirectGotoNodeBuilder(ExplodedNode* pred, CFGBlock* src, Expr* e,
- CFGBlock* dispatch, GRCoreEngine* eng)
- : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
-
- class iterator {
- CFGBlock::succ_iterator I;
-
- friend class GRIndirectGotoNodeBuilder;
- iterator(CFGBlock::succ_iterator i) : I(i) {}
- public:
-
- iterator& operator++() { ++I; return *this; }
- bool operator!=(const iterator& X) const { return I != X.I; }
-
- LabelStmt* getLabel() const {
- return llvm::cast<LabelStmt>((*I)->getLabel());
- }
-
- CFGBlock* getBlock() const {
- return *I;
- }
- };
-
- iterator begin() { return iterator(DispatchBlock.succ_begin()); }
- iterator end() { return iterator(DispatchBlock.succ_end()); }
-
- ExplodedNode* generateNode(const iterator& I, const GRState* State,
- bool isSink = false);
-
- Expr* getTarget() const { return E; }
-
- const GRState* getState() const { return Pred->State; }
-};
-
-class GRSwitchNodeBuilder {
- GRCoreEngine& Eng;
- CFGBlock* Src;
- Expr* Condition;
- ExplodedNode* Pred;
-
-public:
- GRSwitchNodeBuilder(ExplodedNode* pred, CFGBlock* src,
- Expr* condition, GRCoreEngine* eng)
- : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
-
- class iterator {
- CFGBlock::succ_reverse_iterator I;
-
- friend class GRSwitchNodeBuilder;
- iterator(CFGBlock::succ_reverse_iterator i) : I(i) {}
-
- public:
- iterator& operator++() { ++I; return *this; }
- bool operator!=(const iterator& X) const { return I != X.I; }
-
- CaseStmt* getCase() const {
- return llvm::cast<CaseStmt>((*I)->getLabel());
- }
-
- CFGBlock* getBlock() const {
- return *I;
- }
- };
-
- iterator begin() { return iterator(Src->succ_rbegin()+1); }
- iterator end() { return iterator(Src->succ_rend()); }
-
- ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State);
-
- ExplodedNode* generateDefaultCaseNode(const GRState* State,
- bool isSink = false);
-
- Expr* getCondition() const { return Condition; }
-
- const GRState* getState() const { return Pred->State; }
-};
-
-class GREndPathNodeBuilder {
- GRCoreEngine &Eng;
- CFGBlock& B;
- ExplodedNode* Pred;
-
-public:
- bool HasGeneratedNode;
-
-public:
- GREndPathNodeBuilder(CFGBlock* b, ExplodedNode* N, GRCoreEngine* e)
- : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
-
- ~GREndPathNodeBuilder();
-
- GRWorkList &getWorkList() { return *Eng.WList; }
-
- ExplodedNode* getPredecessor() const { return Pred; }
-
- GRBlockCounter getBlockCounter() const {
- return Eng.WList->getBlockCounter();
- }
-
- unsigned getCurrentBlockCount() const {
- return getBlockCounter().getNumVisited(B.getBlockID());
- }
-
- ExplodedNode* generateNode(const GRState* State, const void *tag = 0,
- ExplodedNode *P = 0);
-
- CFGBlock* getBlock() const { return &B; }
-
- const GRState* getState() const {
- return getPredecessor()->getState();
- }
-};
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
deleted file mode 100644
index df90ad9f7f08..000000000000
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ /dev/null
@@ -1,433 +0,0 @@
-//===-- GRExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a meta-engine for path-sensitive dataflow analysis that
-// is built on GRCoreEngine, but provides the boilerplate to execute transfer
-// functions and build the ExplodedGraph at the expression level.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
-#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
-
-#include "clang/Analysis/PathSensitive/AnalysisManager.h"
-#include "clang/Analysis/PathSensitive/GRSubEngine.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprCXX.h"
-
-namespace clang {
-
- class PathDiagnosticClient;
- class Diagnostic;
- class ObjCForCollectionStmt;
- class Checker;
-
-class GRExprEngine : public GRSubEngine {
- AnalysisManager &AMgr;
-
- GRCoreEngine CoreEngine;
-
- /// G - the simulation graph.
- ExplodedGraph& G;
-
- /// Builder - The current GRStmtNodeBuilder which is used when building the
- /// nodes for a given statement.
- GRStmtNodeBuilder* Builder;
-
- /// StateMgr - Object that manages the data for all created states.
- GRStateManager StateMgr;
-
- /// SymMgr - Object that manages the symbol information.
- SymbolManager& SymMgr;
-
- /// ValMgr - Object that manages/creates SVals.
- ValueManager &ValMgr;
-
- /// SVator - SValuator object that creates SVals from expressions.
- SValuator &SVator;
-
- /// EntryNode - The immediate predecessor node.
- ExplodedNode* EntryNode;
-
- /// CleanedState - The state for EntryNode "cleaned" of all dead
- /// variables and symbols (as determined by a liveness analysis).
- const GRState* CleanedState;
-
- /// CurrentStmt - The current block-level statement.
- Stmt* CurrentStmt;
-
- // Obj-C Class Identifiers.
- IdentifierInfo* NSExceptionII;
-
- // Obj-C Selectors.
- Selector* NSExceptionInstanceRaiseSelectors;
- Selector RaiseSel;
-
- llvm::OwningPtr<GRSimpleAPICheck> BatchAuditor;
-
- typedef llvm::DenseMap<void *, unsigned> CheckerMap;
- CheckerMap CheckerM;
-
- typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
- CheckersOrdered Checkers;
-
- /// BR - The BugReporter associated with this engine. It is important that
- // this object be placed at the very end of member variables so that its
- // destructor is called before the rest of the GRExprEngine is destroyed.
- GRBugReporter BR;
-
- llvm::OwningPtr<GRTransferFuncs> TF;
-
-public:
- GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf);
-
- ~GRExprEngine();
-
- void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
- CoreEngine.ExecuteWorkList(L, Steps);
- }
-
- /// getContext - Return the ASTContext associated with this analysis.
- ASTContext& getContext() const { return G.getContext(); }
-
- AnalysisManager &getAnalysisManager() const { return AMgr; }
-
- SValuator &getSValuator() { return SVator; }
-
- GRTransferFuncs& getTF() { return *TF; }
-
- BugReporter& getBugReporter() { return BR; }
-
- GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
-
- // FIXME: Remove once GRTransferFuncs is no longer referenced.
- void setTransferFunction(GRTransferFuncs* tf);
-
- /// ViewGraph - Visualize the ExplodedGraph created by executing the
- /// simulation.
- void ViewGraph(bool trim = false);
-
- void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
-
- /// getInitialState - Return the initial state used for the root vertex
- /// in the ExplodedGraph.
- const GRState* getInitialState(const LocationContext *InitLoc);
-
- ExplodedGraph& getGraph() { return G; }
- const ExplodedGraph& getGraph() const { return G; }
-
- template <typename CHECKER>
- void registerCheck(CHECKER *check) {
- unsigned entry = Checkers.size();
- void *tag = CHECKER::getTag();
- Checkers.push_back(std::make_pair(tag, check));
- CheckerM[tag] = entry;
- }
-
- Checker *lookupChecker(void *tag) const;
-
- template <typename CHECKER>
- CHECKER *getChecker() const {
- return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
- }
-
- void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
- void AddCheck(GRSimpleAPICheck* A);
-
- /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
- /// nodes by processing the 'effects' of a block-level statement.
- void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder);
-
- /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
- /// a CFGBlock. This method returns true if the analysis should continue
- /// exploring the given path, and false otherwise.
- bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
- GRBlockCounter BC);
-
- /// ProcessBranch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a branch condition.
- void ProcessBranch(Stmt* Condition, Stmt* Term, GRBranchNodeBuilder& builder);
-
- /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a computed goto jump.
- void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder);
-
- /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a switch statement.
- void ProcessSwitch(GRSwitchNodeBuilder& builder);
-
- /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
- /// nodes when the control reaches the end of a function.
- void ProcessEndPath(GREndPathNodeBuilder& builder);
-
- /// EvalAssume - Callback function invoked by the ConstraintManager when
- /// making assumptions about state values.
- const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption);
-
- GRStateManager& getStateManager() { return StateMgr; }
- const GRStateManager& getStateManager() const { return StateMgr; }
-
- StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
-
- ConstraintManager& getConstraintManager() {
- return StateMgr.getConstraintManager();
- }
-
- // FIXME: Remove when we migrate over to just using ValueManager.
- BasicValueFactory& getBasicVals() {
- return StateMgr.getBasicVals();
- }
- const BasicValueFactory& getBasicVals() const {
- return StateMgr.getBasicVals();
- }
-
- ValueManager &getValueManager() { return ValMgr; }
- const ValueManager &getValueManager() const { return ValMgr; }
-
- // FIXME: Remove when we migrate over to just using ValueManager.
- SymbolManager& getSymbolManager() { return SymMgr; }
- const SymbolManager& getSymbolManager() const { return SymMgr; }
-
-protected:
- const GRState* GetState(ExplodedNode* N) {
- return N == EntryNode ? CleanedState : N->getState();
- }
-
-public:
- ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
- const GRState* St,
- ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
- const void *tag = 0);
-protected:
- /// CheckerVisit - Dispatcher for performing checker-specific logic
- /// at specific statements.
- void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
- bool isPrevisit);
-
- bool CheckerEvalCall(const CallExpr *CE,
- ExplodedNodeSet &Dst,
- ExplodedNode *Pred);
-
- void CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
- ExplodedNodeSet &Dst,
- const GRState *state,
- ExplodedNode *Pred);
-
- void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
- ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
- SVal location, SVal val, bool isPrevisit);
-
-
- /// Visit - Transfer function logic for all statements. Dispatches to
- /// other functions that handle specific kinds of statements.
- void Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitLValue - Evaluate the lvalue of the expression. For example, if Ex is
- /// a DeclRefExpr, it evaluates to the MemRegionVal which represents its
- /// storage location. Note that not all kinds of expressions has lvalue.
- void VisitLValue(Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitArraySubscriptExpr - Transfer function for array accesses.
- void VisitArraySubscriptExpr(ArraySubscriptExpr* Ex, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- /// VisitAsmStmt - Transfer function logic for inline asm.
- void VisitAsmStmt(AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- void VisitAsmStmtHelperOutputs(AsmStmt* A,
- AsmStmt::outputs_iterator I,
- AsmStmt::outputs_iterator E,
- ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- void VisitAsmStmtHelperInputs(AsmStmt* A,
- AsmStmt::inputs_iterator I,
- AsmStmt::inputs_iterator E,
- ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitBlockExpr - Transfer function logic for BlockExprs.
- void VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst);
-
- /// VisitBinaryOperator - Transfer function logic for binary operators.
- void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
-
- /// VisitCall - Transfer function for function calls.
- void VisitCall(CallExpr* CE, ExplodedNode* Pred,
- CallExpr::arg_iterator AI, CallExpr::arg_iterator AE,
- ExplodedNodeSet& Dst, bool asLValue);
-
- /// VisitCast - Transfer function logic for all casts (implicit and explicit).
- void VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred,
- ExplodedNodeSet &Dst, bool asLValue);
-
- /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
- void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
- void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
- void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- /// VisitDeclStmt - Transfer function logic for DeclStmts.
- void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
- void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
-
- /// VisitCondInit - Transfer function for handling the initialization
- /// of a condition variable in an IfStmt, SwitchStmt, etc.
- void VisitCondInit(VarDecl *VD, Stmt *S, ExplodedNode *Pred,
- ExplodedNodeSet& Dst);
-
- void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
-
- /// VisitLogicalExpr - Transfer function logic for '&&', '||'
- void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
-
- /// VisitMemberExpr - Transfer function for member expressions.
- void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,
- bool asLValue);
-
- /// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs.
- void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- /// VisitObjCForCollectionStmt - Transfer function logic for
- /// ObjCForCollectionStmt.
- void VisitObjCForCollectionStmt(ObjCForCollectionStmt* S, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
-
- void VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
- ExplodedNode* Pred,
- ExplodedNodeSet& Dst, SVal ElementV);
-
- /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
- void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- void VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
- ObjCMessageExpr::arg_iterator I,
- ObjCMessageExpr::arg_iterator E,
- ExplodedNode* Pred, ExplodedNodeSet& Dst,
- bool asLValue);
-
- void VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
- ExplodedNode* Pred,
- ExplodedNodeSet& Dst,
- bool asLValue);
-
- /// VisitReturnStmt - Transfer function logic for return statements.
- void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
-
- /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
- void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
- ExplodedNodeSet& Dst);
-
- /// VisitUnaryOperator - Transfer function logic for unary operators.
- void VisitUnaryOperator(UnaryOperator* B, ExplodedNode* Pred,
- ExplodedNodeSet& Dst, bool asLValue);
-
- void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred,
- ExplodedNodeSet & Dst);
-
- /// Create a C++ temporary object for an rvalue.
- void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
- /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
- /// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
- /// with those assumptions.
- void EvalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, Expr *Ex);
-
- SVal EvalMinus(SVal X) {
- return X.isValid() ? SVator.EvalMinus(cast<NonLoc>(X)) : X;
- }
-
- SVal EvalComplement(SVal X) {
- return X.isValid() ? SVator.EvalComplement(cast<NonLoc>(X)) : X;
- }
-
-public:
-
- SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
- NonLoc L, NonLoc R, QualType T) {
- return SVator.EvalBinOpNN(state, op, L, R, T);
- }
-
- SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode op,
- NonLoc L, SVal R, QualType T) {
- return R.isValid() ? SVator.EvalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
- }
-
- SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
- SVal LHS, SVal RHS, QualType T) {
- return SVator.EvalBinOp(ST, Op, LHS, RHS, T);
- }
-
-protected:
- void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME,
- ExplodedNode* Pred, const GRState *state) {
- assert (Builder && "GRStmtNodeBuilder must be defined.");
- getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
- }
-
- const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
- bool branchTaken);
-
- /// EvalBind - Handle the semantics of binding a value to a specific location.
- /// This method is used by EvalStore, VisitDeclStmt, and others.
- void EvalBind(ExplodedNodeSet& Dst, Stmt *AssignE,
- Stmt* StoreE, ExplodedNode* Pred,
- const GRState* St, SVal location, SVal Val,
- bool atDeclInit = false);
-
-public:
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
- void EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
- const GRState* St, SVal location, const void *tag = 0,
- QualType LoadTy = QualType());
-
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
- void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
- ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
- const void *tag = 0);
-private:
- void EvalLoadCommon(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
- const GRState* St, SVal location, const void *tag,
- QualType LoadTy);
-
- // FIXME: 'tag' should be removed, and a LocationContext should be used
- // instead.
- void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
- const GRState* St, SVal location,
- const void *tag, bool isLoad);
-};
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h b/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h
deleted file mode 100644
index 60db406cd13d..000000000000
--- a/include/clang/Analysis/PathSensitive/GRExprEngineBuilders.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===-- GRExprEngineBuilders.h - "Builder" classes for GRExprEngine -*- C++ -*-=
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines smart builder "references" which are used to marshal
-// builders between GRExprEngine objects and their related components.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
-#define LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/Analysis/Support/SaveAndRestore.h"
-
-namespace clang {
-
-class GRStmtNodeBuilderRef {
- ExplodedNodeSet &Dst;
- GRStmtNodeBuilder &B;
- GRExprEngine& Eng;
- ExplodedNode* Pred;
- const GRState* state;
- const Stmt* stmt;
- const unsigned OldSize;
- const bool AutoCreateNode;
- SaveAndRestore<bool> OldSink;
- SaveAndRestore<const void*> OldTag;
- SaveOr OldHasGen;
-
-private:
- friend class GRExprEngine;
-
- GRStmtNodeBuilderRef(); // do not implement
- void operator=(const GRStmtNodeBuilderRef&); // do not implement
-
- GRStmtNodeBuilderRef(ExplodedNodeSet &dst,
- GRStmtNodeBuilder &builder,
- GRExprEngine& eng,
- ExplodedNode* pred,
- const GRState *st,
- const Stmt* s, bool auto_create_node)
- : Dst(dst), B(builder), Eng(eng), Pred(pred),
- state(st), stmt(s), OldSize(Dst.size()), AutoCreateNode(auto_create_node),
- OldSink(B.BuildSinks), OldTag(B.Tag), OldHasGen(B.HasGeneratedNode) {}
-
-public:
-
- ~GRStmtNodeBuilderRef() {
- // Handle the case where no nodes where generated. Auto-generate that
- // contains the updated state if we aren't generating sinks.
- if (!B.BuildSinks && Dst.size() == OldSize && !B.HasGeneratedNode) {
- if (AutoCreateNode)
- B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state);
- else
- Dst.Add(Pred);
- }
- }
-
- const GRState *getState() { return state; }
-
- GRStateManager& getStateManager() {
- return Eng.getStateManager();
- }
-
- ExplodedNode* MakeNode(const GRState* state) {
- return B.MakeNode(Dst, const_cast<Stmt*>(stmt), Pred, state);
- }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h b/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
deleted file mode 100644
index 978ff0889e64..000000000000
--- a/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// GRCheckAPI.h - Simple API checks based on GRAuditor ------------*- C++ -*--//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface for building simple, path-sensitive checks
-// that are stateless and only emit warnings at errors that occur at
-// CallExpr or ObjCMessageExpr.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS
-#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
-
-#include "clang/Analysis/PathSensitive/GRAuditor.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-
-namespace clang {
-
-class Diagnostic;
-class BugReporter;
-class ASTContext;
-class GRExprEngine;
-class PathDiagnosticClient;
-class ExplodedGraph;
-
-
-class GRSimpleAPICheck : public GRAuditor {
-public:
- GRSimpleAPICheck() {}
- virtual ~GRSimpleAPICheck() {}
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
deleted file mode 100644
index 11cdac0e96de..000000000000
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ /dev/null
@@ -1,751 +0,0 @@
-//== GRState*h - Path-Sens. "State" for tracking valuues -----*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines SymbolRef, ExprBindKey, and GRState*
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
-#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
-
-// FIXME: Reduce the number of includes.
-
-#include "clang/Analysis/PathSensitive/Environment.h"
-#include "clang/Analysis/PathSensitive/Store.h"
-#include "clang/Analysis/PathSensitive/ConstraintManager.h"
-#include "clang/Analysis/PathSensitive/ValueManager.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/System/DataTypes.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <functional>
-
-namespace clang {
-
-class GRStateManager;
-class Checker;
-
-typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&,
- GRSubEngine&);
-typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
-
-//===----------------------------------------------------------------------===//
-// GRStateTrait - Traits used by the Generic Data Map of a GRState.
-//===----------------------------------------------------------------------===//
-
-template <typename T> struct GRStatePartialTrait;
-
-template <typename T> struct GRStateTrait {
- typedef typename T::data_type data_type;
- static inline void* GDMIndex() { return &T::TagInt; }
- static inline void* MakeVoidPtr(data_type D) { return (void*) D; }
- static inline data_type MakeData(void* const* P) {
- return P ? (data_type) *P : (data_type) 0;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// GRState- An ImmutableMap type Stmt*/Decl*/Symbols to SVals.
-//===----------------------------------------------------------------------===//
-
-class GRStateManager;
-
-/// GRState - This class encapsulates the actual data values for
-/// for a "state" in our symbolic value tracking. It is intended to be
-/// used as a functional object; that is once it is created and made
-/// "persistent" in a FoldingSet its values will never change.
-class GRState : public llvm::FoldingSetNode {
-public:
- typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
- typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
-
-private:
- void operator=(const GRState& R) const;
-
- friend class GRStateManager;
-
- GRStateManager *StateMgr;
- Environment Env;
- Store St;
-
- // FIXME: Make these private.
-public:
- GenericDataMap GDM;
-
-public:
-
- /// This ctor is used when creating the first GRState object.
- GRState(GRStateManager *mgr, const Environment& env,
- Store st, GenericDataMap gdm)
- : StateMgr(mgr),
- Env(env),
- St(st),
- GDM(gdm) {}
-
- /// Copy ctor - We must explicitly define this or else the "Next" ptr
- /// in FoldingSetNode will also get copied.
- GRState(const GRState& RHS)
- : llvm::FoldingSetNode(),
- StateMgr(RHS.StateMgr),
- Env(RHS.Env),
- St(RHS.St),
- GDM(RHS.GDM) {}
-
- /// getStateManager - Return the GRStateManager associated with this state.
- GRStateManager &getStateManager() const {
- return *StateMgr;
- }
-
- /// getAnalysisContext - Return the AnalysisContext associated with this
- /// state.
- AnalysisContext &getAnalysisContext() const {
- return Env.getAnalysisContext();
- }
-
- /// getEnvironment - Return the environment associated with this state.
- /// The environment is the mapping from expressions to values.
- const Environment& getEnvironment() const { return Env; }
-
- /// getStore - Return the store associated with this state. The store
- /// is a mapping from locations to values.
- Store getStore() const { return St; }
-
- void setStore(Store s) { St = s; }
-
- /// getGDM - Return the generic data map associated with this state.
- GenericDataMap getGDM() const { return GDM; }
-
- void setGDM(GenericDataMap gdm) { GDM = gdm; }
-
- /// Profile - Profile the contents of a GRState object for use
- /// in a FoldingSet.
- static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
- // FIXME: Do we need to include the AnalysisContext in the profile?
- V->Env.Profile(ID);
- ID.AddPointer(V->St);
- V->GDM.Profile(ID);
- }
-
- /// Profile - Used to profile the contents of this object for inclusion
- /// in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- Profile(ID, this);
- }
-
- SVal LookupExpr(Expr* E) const {
- return Env.LookupExpr(E);
- }
-
- /// makeWithStore - Return a GRState with the same values as the current
- /// state with the exception of using the specified Store.
- const GRState *makeWithStore(Store store) const;
-
- BasicValueFactory &getBasicVals() const;
- SymbolManager &getSymbolManager() const;
-
- //==---------------------------------------------------------------------==//
- // Constraints on values.
- //==---------------------------------------------------------------------==//
- //
- // Each GRState records constraints on symbolic values. These constraints
- // are managed using the ConstraintManager associated with a GRStateManager.
- // As constraints gradually accrue on symbolic values, added constraints
- // may conflict and indicate that a state is infeasible (as no real values
- // could satisfy all the constraints). This is the principal mechanism
- // for modeling path-sensitivity in GRExprEngine/GRState.
- //
- // Various "Assume" methods form the interface for adding constraints to
- // symbolic values. A call to "Assume" indicates an assumption being placed
- // on one or symbolic values. Assume methods take the following inputs:
- //
- // (1) A GRState object representing the current state.
- //
- // (2) The assumed constraint (which is specific to a given "Assume" method).
- //
- // (3) A binary value "Assumption" that indicates whether the constraint is
- // assumed to be true or false.
- //
- // The output of "Assume" are two values:
- //
- // (a) "isFeasible" is set to true or false to indicate whether or not
- // the assumption is feasible.
- //
- // (b) A new GRState object with the added constraints.
- //
- // FIXME: (a) should probably disappear since it is redundant with (b).
- // (i.e., (b) could just be set to NULL).
- //
-
- const GRState *Assume(DefinedOrUnknownSVal cond, bool assumption) const;
-
- std::pair<const GRState*, const GRState*>
- Assume(DefinedOrUnknownSVal cond) const;
-
- const GRState *AssumeInBound(DefinedOrUnknownSVal idx,
- DefinedOrUnknownSVal upperBound,
- bool assumption) const;
-
- //==---------------------------------------------------------------------==//
- // Utility methods for getting regions.
- //==---------------------------------------------------------------------==//
-
- const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
-
- //==---------------------------------------------------------------------==//
- // Binding and retrieving values to/from the environment and symbolic store.
- //==---------------------------------------------------------------------==//
-
- /// BindCompoundLiteral - Return the state that has the bindings currently
- /// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region
- /// for the compound literal and 'BegInit' and 'EndInit' represent an
- /// array of initializer values.
- const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
- const LocationContext *LC,
- SVal V) const;
-
- const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
-
- const GRState *bindDecl(const VarRegion *VR, SVal V) const;
-
- const GRState *bindDeclWithNoInit(const VarRegion *VR) const;
-
- const GRState *bindLoc(Loc location, SVal V) const;
-
- const GRState *bindLoc(SVal location, SVal V) const;
-
- const GRState *unbindLoc(Loc LV) const;
-
- /// Get the lvalue for a variable reference.
- SVal getLValue(const VarDecl *D, const LocationContext *LC) const;
-
- /// Get the lvalue for a StringLiteral.
- SVal getLValue(const StringLiteral *literal) const;
-
- SVal getLValue(const CompoundLiteralExpr *literal,
- const LocationContext *LC) const;
-
- /// Get the lvalue for an ivar reference.
- SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
-
- /// Get the lvalue for a field reference.
- SVal getLValue(const FieldDecl *decl, SVal Base) const;
-
- /// Get the lvalue for an array index.
- SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
-
- const llvm::APSInt *getSymVal(SymbolRef sym) const;
-
- SVal getSVal(const Stmt* Ex) const;
-
- SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
-
- SVal getSVal(Loc LV, QualType T = QualType()) const;
-
- SVal getSVal(const MemRegion* R) const;
-
- SVal getSValAsScalarOrLoc(const MemRegion *R) const;
-
- const llvm::APSInt *getSymVal(SymbolRef sym);
-
- bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
-
- bool scanReachableSymbols(const SVal *I, const SVal *E,
- SymbolVisitor &visitor) const;
-
- bool scanReachableSymbols(const MemRegion * const *I,
- const MemRegion * const *E,
- SymbolVisitor &visitor) const;
-
- template <typename CB> CB scanReachableSymbols(SVal val) const;
- template <typename CB> CB scanReachableSymbols(const SVal *beg,
- const SVal *end) const;
-
- template <typename CB> CB
- scanReachableSymbols(const MemRegion * const *beg,
- const MemRegion * const *end) const;
-
- //==---------------------------------------------------------------------==//
- // Accessing the Generic Data Map (GDM).
- //==---------------------------------------------------------------------==//
-
- void* const* FindGDM(void* K) const;
-
- template<typename T>
- const GRState *add(typename GRStateTrait<T>::key_type K) const;
-
- template <typename T>
- typename GRStateTrait<T>::data_type
- get() const {
- return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex()));
- }
-
- template<typename T>
- typename GRStateTrait<T>::lookup_type
- get(typename GRStateTrait<T>::key_type key) const {
- void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
- return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key);
- }
-
- template <typename T>
- typename GRStateTrait<T>::context_type get_context() const;
-
-
- template<typename T>
- const GRState *remove(typename GRStateTrait<T>::key_type K) const;
-
- template<typename T>
- const GRState *remove(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::context_type C) const;
-
- template<typename T>
- const GRState *set(typename GRStateTrait<T>::data_type D) const;
-
- template<typename T>
- const GRState *set(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type E) const;
-
- template<typename T>
- const GRState *set(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type E,
- typename GRStateTrait<T>::context_type C) const;
-
- template<typename T>
- bool contains(typename GRStateTrait<T>::key_type key) const {
- void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
- return GRStateTrait<T>::Contains(GRStateTrait<T>::MakeData(d), key);
- }
-
- // State pretty-printing.
- class Printer {
- public:
- virtual ~Printer() {}
- virtual void Print(llvm::raw_ostream& Out, const GRState* state,
- const char* nl, const char* sep) = 0;
- };
-
- // Pretty-printing.
- void print(llvm::raw_ostream& Out, const char *nl = "\n",
- const char *sep = "") const;
-
- void printStdErr() const;
-
- void printDOT(llvm::raw_ostream& Out) const;
-};
-
-class GRStateSet {
- typedef llvm::SmallPtrSet<const GRState*,5> ImplTy;
- ImplTy Impl;
-public:
- GRStateSet() {}
-
- inline void Add(const GRState* St) {
- Impl.insert(St);
- }
-
- typedef ImplTy::const_iterator iterator;
-
- inline unsigned size() const { return Impl.size(); }
- inline bool empty() const { return Impl.empty(); }
-
- inline iterator begin() const { return Impl.begin(); }
- inline iterator end() const { return Impl.end(); }
-
- class AutoPopulate {
- GRStateSet& S;
- unsigned StartSize;
- const GRState* St;
- public:
- AutoPopulate(GRStateSet& s, const GRState* st)
- : S(s), StartSize(S.size()), St(st) {}
-
- ~AutoPopulate() {
- if (StartSize == S.size())
- S.Add(St);
- }
- };
-};
-
-//===----------------------------------------------------------------------===//
-// GRStateManager - Factory object for GRStates.
-//===----------------------------------------------------------------------===//
-
-class GRStateManager {
- friend class GRState;
- friend class GRExprEngine; // FIXME: Remove.
-private:
- EnvironmentManager EnvMgr;
- llvm::OwningPtr<StoreManager> StoreMgr;
- llvm::OwningPtr<ConstraintManager> ConstraintMgr;
-
- GRState::GenericDataMap::Factory GDMFactory;
-
- typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
- GDMContextsTy GDMContexts;
-
- /// Printers - A set of printer objects used for pretty-printing a GRState.
- /// GRStateManager owns these objects.
- std::vector<GRState::Printer*> Printers;
-
- /// StateSet - FoldingSet containing all the states created for analyzing
- /// a particular function. This is used to unique states.
- llvm::FoldingSet<GRState> StateSet;
-
- /// ValueMgr - Object that manages the data for all created SVals.
- ValueManager ValueMgr;
-
- /// Alloc - A BumpPtrAllocator to allocate states.
- llvm::BumpPtrAllocator &Alloc;
-
-public:
- GRStateManager(ASTContext& Ctx,
- StoreManagerCreator CreateStoreManager,
- ConstraintManagerCreator CreateConstraintManager,
- llvm::BumpPtrAllocator& alloc,
- GRSubEngine &subeng)
- : EnvMgr(alloc),
- GDMFactory(alloc),
- ValueMgr(alloc, Ctx, *this),
- Alloc(alloc) {
- StoreMgr.reset((*CreateStoreManager)(*this));
- ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
- }
-
- ~GRStateManager();
-
- const GRState *getInitialState(const LocationContext *InitLoc);
-
- ASTContext &getContext() { return ValueMgr.getContext(); }
- const ASTContext &getContext() const { return ValueMgr.getContext(); }
-
- BasicValueFactory &getBasicVals() {
- return ValueMgr.getBasicValueFactory();
- }
- const BasicValueFactory& getBasicVals() const {
- return ValueMgr.getBasicValueFactory();
- }
-
- SymbolManager &getSymbolManager() {
- return ValueMgr.getSymbolManager();
- }
- const SymbolManager &getSymbolManager() const {
- return ValueMgr.getSymbolManager();
- }
-
- ValueManager &getValueManager() { return ValueMgr; }
- const ValueManager &getValueManager() const { return ValueMgr; }
-
- llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
-
- MemRegionManager& getRegionManager() {
- return ValueMgr.getRegionManager();
- }
- const MemRegionManager& getRegionManager() const {
- return ValueMgr.getRegionManager();
- }
-
- StoreManager& getStoreManager() { return *StoreMgr; }
- ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
-
- const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc,
- SymbolReaper& SymReaper);
-
-public:
-
- SVal ArrayToPointer(Loc Array) {
- return StoreMgr->ArrayToPointer(Array);
- }
-
- // Methods that manipulate the GDM.
- const GRState* addGDM(const GRState* St, void* Key, void* Data);
-
- // Methods that query & manipulate the Store.
-
- void iterBindings(const GRState* state, StoreManager::BindingsHandler& F) {
- StoreMgr->iterBindings(state->getStore(), F);
- }
-
- const GRState* getPersistentState(GRState& Impl);
-
- bool isEqual(const GRState* state, const Expr* Ex, const llvm::APSInt& V);
- bool isEqual(const GRState* state, const Expr* Ex, uint64_t);
-
- //==---------------------------------------------------------------------==//
- // Generic Data Map methods.
- //==---------------------------------------------------------------------==//
- //
- // GRStateManager and GRState support a "generic data map" that allows
- // different clients of GRState objects to embed arbitrary data within a
- // GRState object. The generic data map is essentially an immutable map
- // from a "tag" (that acts as the "key" for a client) and opaque values.
- // Tags/keys and values are simply void* values. The typical way that clients
- // generate unique tags are by taking the address of a static variable.
- // Clients are responsible for ensuring that data values referred to by a
- // the data pointer are immutable (and thus are essentially purely functional
- // data).
- //
- // The templated methods below use the GRStateTrait<T> class
- // to resolve keys into the GDM and to return data values to clients.
- //
-
- // Trait based GDM dispatch.
- template <typename T>
- const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) {
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(D));
- }
-
- template<typename T>
- const GRState* set(const GRState* st,
- typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type V,
- typename GRStateTrait<T>::context_type C) {
-
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
- }
-
- template <typename T>
- const GRState* add(const GRState* st,
- typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::context_type C) {
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C)));
- }
-
- template <typename T>
- const GRState* remove(const GRState* st,
- typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::context_type C) {
-
- return addGDM(st, GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
- }
-
-
- void* FindGDMContext(void* index,
- void* (*CreateContext)(llvm::BumpPtrAllocator&),
- void (*DeleteContext)(void*));
-
- template <typename T>
- typename GRStateTrait<T>::context_type get_context() {
- void* p = FindGDMContext(GRStateTrait<T>::GDMIndex(),
- GRStateTrait<T>::CreateContext,
- GRStateTrait<T>::DeleteContext);
-
- return GRStateTrait<T>::MakeContext(p);
- }
-
- const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) {
- return ConstraintMgr->getSymVal(St, sym);
- }
-
- void EndPath(const GRState* St) {
- ConstraintMgr->EndPath(St);
- }
-};
-
-
-//===----------------------------------------------------------------------===//
-// Out-of-line method definitions for GRState.
-//===----------------------------------------------------------------------===//
-
-inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) {
- return getStateManager().getSymVal(this, sym);
-}
-
-inline const VarRegion* GRState::getRegion(const VarDecl *D,
- const LocationContext *LC) const {
- return getStateManager().getRegionManager().getVarRegion(D, LC);
-}
-
-inline const GRState *GRState::Assume(DefinedOrUnknownSVal Cond,
- bool Assumption) const {
- if (Cond.isUnknown())
- return this;
-
- return getStateManager().ConstraintMgr->Assume(this, cast<DefinedSVal>(Cond),
- Assumption);
-}
-
-inline std::pair<const GRState*, const GRState*>
-GRState::Assume(DefinedOrUnknownSVal Cond) const {
- if (Cond.isUnknown())
- return std::make_pair(this, this);
-
- return getStateManager().ConstraintMgr->AssumeDual(this,
- cast<DefinedSVal>(Cond));
-}
-
-inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
- DefinedOrUnknownSVal UpperBound,
- bool Assumption) const {
- if (Idx.isUnknown() || UpperBound.isUnknown())
- return this;
-
- ConstraintManager &CM = *getStateManager().ConstraintMgr;
- return CM.AssumeInBound(this, cast<DefinedSVal>(Idx),
- cast<DefinedSVal>(UpperBound), Assumption);
-}
-
-inline const GRState *
-GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
- const LocationContext *LC, SVal V) const {
- return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, LC, V);
-}
-
-inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
- return getStateManager().StoreMgr->BindDecl(this, VR, IVal);
-}
-
-inline const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
- return getStateManager().StoreMgr->BindDeclWithNoInit(this, VR);
-}
-
-inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
- return getStateManager().StoreMgr->Bind(this, LV, V);
-}
-
-inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
- return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
-}
-
-inline SVal GRState::getLValue(const VarDecl* VD,
- const LocationContext *LC) const {
- return getStateManager().StoreMgr->getLValueVar(VD, LC);
-}
-
-inline SVal GRState::getLValue(const StringLiteral *literal) const {
- return getStateManager().StoreMgr->getLValueString(literal);
-}
-
-inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
- const LocationContext *LC) const {
- return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
-}
-
-inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
- return getStateManager().StoreMgr->getLValueIvar(D, Base);
-}
-
-inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const {
- return getStateManager().StoreMgr->getLValueField(D, Base);
-}
-
-inline SVal GRState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
- return getStateManager().StoreMgr->getLValueElement(ElementType, Idx, Base);
-}
-
-inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
- return getStateManager().getSymVal(this, sym);
-}
-
-inline SVal GRState::getSVal(const Stmt* Ex) const {
- return Env.GetSVal(Ex, getStateManager().ValueMgr);
-}
-
-inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
- if (const Expr *Ex = dyn_cast<Expr>(S)) {
- QualType T = Ex->getType();
- if (Loc::IsLocType(T) || T->isIntegerType())
- return getSVal(S);
- }
-
- return UnknownVal();
-}
-
-inline SVal GRState::getSVal(Loc LV, QualType T) const {
- return getStateManager().StoreMgr->Retrieve(this, LV, T).getSVal();
-}
-
-inline SVal GRState::getSVal(const MemRegion* R) const {
- return getStateManager().StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
-}
-
-inline BasicValueFactory &GRState::getBasicVals() const {
- return getStateManager().getBasicVals();
-}
-
-inline SymbolManager &GRState::getSymbolManager() const {
- return getStateManager().getSymbolManager();
-}
-
-template<typename T>
-const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
- return getStateManager().add<T>(this, K, get_context<T>());
-}
-
-template <typename T>
-typename GRStateTrait<T>::context_type GRState::get_context() const {
- return getStateManager().get_context<T>();
-}
-
-template<typename T>
-const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const {
- return getStateManager().remove<T>(this, K, get_context<T>());
-}
-
-template<typename T>
-const GRState *GRState::remove(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::context_type C) const {
- return getStateManager().remove<T>(this, K, C);
-}
-
-template<typename T>
-const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const {
- return getStateManager().set<T>(this, D);
-}
-
-template<typename T>
-const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type E) const {
- return getStateManager().set<T>(this, K, E, get_context<T>());
-}
-
-template<typename T>
-const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
- typename GRStateTrait<T>::value_type E,
- typename GRStateTrait<T>::context_type C) const {
- return getStateManager().set<T>(this, K, E, C);
-}
-
-template <typename CB>
-CB GRState::scanReachableSymbols(SVal val) const {
- CB cb(this);
- scanReachableSymbols(val, cb);
- return cb;
-}
-
-template <typename CB>
-CB GRState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
- CB cb(this);
- scanReachableSymbols(beg, end, cb);
- return cb;
-}
-
-template <typename CB>
-CB GRState::scanReachableSymbols(const MemRegion * const *beg,
- const MemRegion * const *end) const {
- CB cb(this);
- scanReachableSymbols(beg, end, cb);
- return cb;
-}
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRStateTrait.h b/include/clang/Analysis/PathSensitive/GRStateTrait.h
deleted file mode 100644
index 5189a1f5aa7e..000000000000
--- a/include/clang/Analysis/PathSensitive/GRStateTrait.h
+++ /dev/null
@@ -1,148 +0,0 @@
-//==- GRStateTrait.h - Partial implementations of GRStateTrait -----*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines partial implementations of template specializations of
-// the class GRStateTrait<>. GRStateTrait<> is used by GRState to implement
-// set/get methods for mapulating a GRState's generic data map.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
-#define LLVM_CLANG_ANALYSIS_GRSTATETRAIT_H
-
-namespace llvm {
- class BumpPtrAllocator;
- template <typename K, typename D, typename I> class ImmutableMap;
- template <typename K, typename I> class ImmutableSet;
- template <typename T> class ImmutableList;
- template <typename T> class ImmutableListImpl;
-}
-
-namespace clang {
- template <typename T> struct GRStatePartialTrait;
-
- // Partial-specialization for ImmutableMap.
-
- template <typename Key, typename Data, typename Info>
- struct GRStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
- typedef llvm::ImmutableMap<Key,Data,Info> data_type;
- typedef typename data_type::Factory& context_type;
- typedef Key key_type;
- typedef Data value_type;
- typedef const value_type* lookup_type;
-
- static inline data_type MakeData(void* const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
- }
- static inline void* MakeVoidPtr(data_type B) {
- return B.getRoot();
- }
- static lookup_type Lookup(data_type B, key_type K) {
- return B.lookup(K);
- }
- static data_type Set(data_type B, key_type K, value_type E,context_type F){
- return F.Add(B, K, E);
- }
-
- static data_type Remove(data_type B, key_type K, context_type F) {
- return F.Remove(B, K);
- }
-
- static inline context_type MakeContext(void* p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void* Ctx) {
- delete (typename data_type::Factory*) Ctx;
- }
- };
-
-
- // Partial-specialization for ImmutableSet.
-
- template <typename Key, typename Info>
- struct GRStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
- typedef llvm::ImmutableSet<Key,Info> data_type;
- typedef typename data_type::Factory& context_type;
- typedef Key key_type;
-
- static inline data_type MakeData(void* const* p) {
- return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
- }
-
- static inline void* MakeVoidPtr(data_type B) {
- return B.getRoot();
- }
-
- static data_type Add(data_type B, key_type K, context_type F) {
- return F.Add(B, K);
- }
-
- static data_type Remove(data_type B, key_type K, context_type F) {
- return F.Remove(B, K);
- }
-
- static bool Contains(data_type B, key_type K) {
- return B.contains(K);
- }
-
- static inline context_type MakeContext(void* p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void* Ctx) {
- delete (typename data_type::Factory*) Ctx;
- }
- };
-
- // Partial-specialization for ImmutableList.
-
- template <typename T>
- struct GRStatePartialTrait< llvm::ImmutableList<T> > {
- typedef llvm::ImmutableList<T> data_type;
- typedef T key_type;
- typedef typename data_type::Factory& context_type;
-
- static data_type Add(data_type L, key_type K, context_type F) {
- return F.Add(K, L);
- }
-
- static inline data_type MakeData(void* const* p) {
- return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
- : data_type(0);
- }
-
- static inline void* MakeVoidPtr(data_type D) {
- return (void*) D.getInternalPointer();
- }
-
- static inline context_type MakeContext(void* p) {
- return *((typename data_type::Factory*) p);
- }
-
- static void* CreateContext(llvm::BumpPtrAllocator& Alloc) {
- return new typename data_type::Factory(Alloc);
- }
-
- static void DeleteContext(void* Ctx) {
- delete (typename data_type::Factory*) Ctx;
- }
- };
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRSubEngine.h b/include/clang/Analysis/PathSensitive/GRSubEngine.h
deleted file mode 100644
index 5b383fae9bd0..000000000000
--- a/include/clang/Analysis/PathSensitive/GRSubEngine.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//== GRSubEngine.h - Interface of the subengine of GRCoreEngine ----*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface of a subengine of the GRCoreEngine.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
-#define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
-
-#include "clang/Analysis/PathSensitive/SVals.h"
-
-namespace clang {
-
-class Stmt;
-class CFGBlock;
-class CFGElement;
-class GRState;
-class GRStateManager;
-class GRBlockCounter;
-class GRStmtNodeBuilder;
-class GRBranchNodeBuilder;
-class GRIndirectGotoNodeBuilder;
-class GRSwitchNodeBuilder;
-class GREndPathNodeBuilder;
-class LocationContext;
-
-class GRSubEngine {
-public:
- virtual ~GRSubEngine() {}
-
- virtual const GRState* getInitialState(const LocationContext *InitLoc) = 0;
-
- virtual GRStateManager& getStateManager() = 0;
-
- /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
- /// nodes by processing the 'effects' of a block-level statement.
- virtual void ProcessStmt(CFGElement E, GRStmtNodeBuilder& builder) = 0;
-
- /// ProcessBlockEntrance - Called by GRCoreEngine when start processing
- /// a CFGBlock. This method returns true if the analysis should continue
- /// exploring the given path, and false otherwise.
- virtual bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
- GRBlockCounter BC) = 0;
-
- /// ProcessBranch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a branch condition.
- virtual void ProcessBranch(Stmt* Condition, Stmt* Term,
- GRBranchNodeBuilder& builder) = 0;
-
- /// ProcessIndirectGoto - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a computed goto jump.
- virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilder& builder) = 0;
-
- /// ProcessSwitch - Called by GRCoreEngine. Used to generate successor
- /// nodes by processing the 'effects' of a switch statement.
- virtual void ProcessSwitch(GRSwitchNodeBuilder& builder) = 0;
-
- /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path
- /// nodes when the control reaches the end of a function.
- virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0;
-
- /// EvalAssume - Called by ConstraintManager. Used to call checker-specific
- /// logic for handling assumptions on symbolic values.
- virtual const GRState* ProcessAssume(const GRState *state,
- SVal cond, bool assumption) = 0;
-};
-}
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
deleted file mode 100644
index b058460a4934..000000000000
--- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//== GRTransferFuncs.h - Path-Sens. Transfer Functions Interface -*- C++ -*--=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines GRTransferFuncs, which provides a base-class that
-// defines an interface for transfer functions used by GRExprEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRTF
-#define LLVM_CLANG_ANALYSIS_GRTF
-
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
-#include "clang/Analysis/PathSensitive/GRState.h"
-#include <vector>
-
-namespace clang {
-
-class GRExprEngine;
-class ObjCMessageExpr;
-class GRStmtNodeBuilderRef;
-
-class GRTransferFuncs {
-public:
- GRTransferFuncs() {}
- virtual ~GRTransferFuncs() {}
-
- virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {}
- virtual void RegisterChecks(GRExprEngine& Eng) {}
-
-
- // Calls.
-
- virtual void EvalCall(ExplodedNodeSet& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder& Builder,
- CallExpr* CE, SVal L,
- ExplodedNode* Pred) {}
-
- virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder& Builder,
- ObjCMessageExpr* ME,
- ExplodedNode* Pred,
- const GRState *state) {}
-
- // Stores.
-
- virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {}
-
- // End-of-path and dead symbol notification.
-
- virtual void EvalEndPath(GRExprEngine& Engine,
- GREndPathNodeBuilder& Builder) {}
-
-
- virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder& Builder,
- ExplodedNode* Pred,
- Stmt* S, const GRState* state,
- SymbolReaper& SymReaper) {}
-
- // Return statements.
- virtual void EvalReturn(ExplodedNodeSet& Dst,
- GRExprEngine& Engine,
- GRStmtNodeBuilder& Builder,
- ReturnStmt* S,
- ExplodedNode* Pred) {}
-
- // Assumptions.
- virtual const GRState* EvalAssume(const GRState *state,
- SVal Cond, bool Assumption) {
- return state;
- }
-};
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/GRWorkList.h b/include/clang/Analysis/PathSensitive/GRWorkList.h
deleted file mode 100644
index 857fa316911f..000000000000
--- a/include/clang/Analysis/PathSensitive/GRWorkList.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//==- GRWorkList.h - Worklist class used by GRCoreEngine -----------*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines GRWorkList, a pure virtual class that represents an opaque
-// worklist used by GRCoreEngine to explore the reachability state space.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
-#define LLVM_CLANG_ANALYSIS_GRWORKLIST
-
-#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
-#include <cstddef>
-
-namespace clang {
-
-class CFGBlock;
-class ExplodedNode;
-class ExplodedNodeImpl;
-
-class GRWorkListUnit {
- ExplodedNode* Node;
- GRBlockCounter Counter;
- CFGBlock* Block;
- unsigned BlockIdx; // This is the index of the next statement.
-
-public:
- GRWorkListUnit(ExplodedNode* N, GRBlockCounter C,
- CFGBlock* B, unsigned idx)
- : Node(N),
- Counter(C),
- Block(B),
- BlockIdx(idx) {}
-
- explicit GRWorkListUnit(ExplodedNode* N, GRBlockCounter C)
- : Node(N),
- Counter(C),
- Block(NULL),
- BlockIdx(0) {}
-
- ExplodedNode* getNode() const { return Node; }
- GRBlockCounter getBlockCounter() const { return Counter; }
- CFGBlock* getBlock() const { return Block; }
- unsigned getIndex() const { return BlockIdx; }
-};
-
-class GRWorkList {
- GRBlockCounter CurrentCounter;
-public:
- virtual ~GRWorkList();
- virtual bool hasWork() const = 0;
-
- virtual void Enqueue(const GRWorkListUnit& U) = 0;
-
- void Enqueue(ExplodedNode* N, CFGBlock& B, unsigned idx) {
- Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
- }
-
- void Enqueue(ExplodedNode* N) {
- Enqueue(GRWorkListUnit(N, CurrentCounter));
- }
-
- virtual GRWorkListUnit Dequeue() = 0;
-
- void setBlockCounter(GRBlockCounter C) { CurrentCounter = C; }
- GRBlockCounter getBlockCounter() const { return CurrentCounter; }
-
- static GRWorkList *MakeDFS();
- static GRWorkList *MakeBFS();
- static GRWorkList *MakeBFSBlockDFSContents();
-};
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
deleted file mode 100644
index 3bcedbefd65c..000000000000
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ /dev/null
@@ -1,971 +0,0 @@
-//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines MemRegion and its subclasses. MemRegion defines a
-// partially-typed abstraction of memory useful for path-sensitive dataflow
-// analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H
-#define LLVM_CLANG_ANALYSIS_MEMREGION_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/AST/ASTContext.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/Support/Allocator.h"
-#include <string>
-
-namespace llvm { class raw_ostream; }
-
-namespace clang {
-
-class MemRegionManager;
-class MemSpaceRegion;
-class LocationContext;
-class StackFrameContext;
-class VarRegion;
-
-//===----------------------------------------------------------------------===//
-// Base region classes.
-//===----------------------------------------------------------------------===//
-
-/// MemRegion - The root abstract class for all memory regions.
-class MemRegion : public llvm::FoldingSetNode {
- friend class MemRegionManager;
-public:
- enum Kind {
- // Memory spaces.
- BEG_MEMSPACES,
- GenericMemSpaceRegionKind = BEG_MEMSPACES,
- StackLocalsSpaceRegionKind,
- StackArgumentsSpaceRegionKind,
- HeapSpaceRegionKind,
- UnknownSpaceRegionKind,
- GlobalsSpaceRegionKind,
- END_MEMSPACES = GlobalsSpaceRegionKind,
- // Untyped regions.
- SymbolicRegionKind,
- AllocaRegionKind,
- // Typed regions.
- BEG_TYPED_REGIONS,
- FunctionTextRegionKind = BEG_TYPED_REGIONS,
- BlockTextRegionKind,
- BlockDataRegionKind,
- CompoundLiteralRegionKind,
- CXXThisRegionKind,
- StringRegionKind,
- ElementRegionKind,
- // Decl Regions.
- BEG_DECL_REGIONS,
- VarRegionKind = BEG_DECL_REGIONS,
- FieldRegionKind,
- ObjCIvarRegionKind,
- CXXObjectRegionKind,
- END_DECL_REGIONS = CXXObjectRegionKind,
- END_TYPED_REGIONS = END_DECL_REGIONS
- };
-
-private:
- const Kind kind;
-
-protected:
- MemRegion(Kind k) : kind(k) {}
- virtual ~MemRegion();
-
-public:
- ASTContext &getContext() const;
-
- virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
-
- virtual MemRegionManager* getMemRegionManager() const = 0;
-
- std::string getString() const;
-
- const MemSpaceRegion *getMemorySpace() const;
-
- const MemRegion *getBaseRegion() const;
-
- const MemRegion *StripCasts() const;
-
- bool hasGlobalsOrParametersStorage() const;
-
- bool hasStackStorage() const;
-
- bool hasStackNonParametersStorage() const;
-
- bool hasStackParametersStorage() const;
-
- virtual void dumpToStream(llvm::raw_ostream& os) const;
-
- void dump() const;
-
- Kind getKind() const { return kind; }
-
- template<typename RegionTy> const RegionTy* getAs() const;
-
- virtual bool isBoundable() const { return false; }
-
- static bool classof(const MemRegion*) { return true; }
-};
-
-/// MemSpaceRegion - A memory region that represents and "memory space";
-/// for example, the set of global variables, the stack frame, etc.
-class MemSpaceRegion : public MemRegion {
-protected:
- friend class MemRegionManager;
-
- MemRegionManager *Mgr;
-
- MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
- : MemRegion(k), Mgr(mgr) {
- assert(classof(this));
- }
-
- MemRegionManager* getMemRegionManager() const { return Mgr; }
-
-public:
- bool isBoundable() const { return false; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
- static bool classof(const MemRegion *R) {
- Kind k = R->getKind();
- return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
- }
-};
-
-class GlobalsSpaceRegion : public MemSpaceRegion {
- friend class MemRegionManager;
-
- GlobalsSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
-public:
- static bool classof(const MemRegion *R) {
- return R->getKind() == GlobalsSpaceRegionKind;
- }
-};
-
-class HeapSpaceRegion : public MemSpaceRegion {
- friend class MemRegionManager;
-
- HeapSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
-public:
- static bool classof(const MemRegion *R) {
- return R->getKind() == HeapSpaceRegionKind;
- }
-};
-
-class UnknownSpaceRegion : public MemSpaceRegion {
- friend class MemRegionManager;
- UnknownSpaceRegion(MemRegionManager *mgr)
- : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
-public:
- static bool classof(const MemRegion *R) {
- return R->getKind() == UnknownSpaceRegionKind;
- }
-};
-
-class StackSpaceRegion : public MemSpaceRegion {
-private:
- const StackFrameContext *SFC;
-
-protected:
- StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
- : MemSpaceRegion(mgr, k), SFC(sfc) {
- assert(classof(this));
- }
-
-public:
- const StackFrameContext *getStackFrame() const { return SFC; }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
- static bool classof(const MemRegion *R) {
- Kind k = R->getKind();
- return k >= StackLocalsSpaceRegionKind &&
- k <= StackArgumentsSpaceRegionKind;
- }
-};
-
-class StackLocalsSpaceRegion : public StackSpaceRegion {
-private:
- friend class MemRegionManager;
- StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
- : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
-public:
- static bool classof(const MemRegion *R) {
- return R->getKind() == StackLocalsSpaceRegionKind;
- }
-};
-
-class StackArgumentsSpaceRegion : public StackSpaceRegion {
-private:
- friend class MemRegionManager;
- StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
- : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
-public:
- static bool classof(const MemRegion *R) {
- return R->getKind() == StackArgumentsSpaceRegionKind;
- }
-};
-
-/// SubRegion - A region that subsets another larger region. Most regions
-/// are subclasses of SubRegion.
-class SubRegion : public MemRegion {
-protected:
- const MemRegion* superRegion;
- SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
-public:
- const MemRegion* getSuperRegion() const {
- return superRegion;
- }
-
- MemRegionManager* getMemRegionManager() const;
-
- bool isSubRegionOf(const MemRegion* R) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() > END_MEMSPACES;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Auxillary data classes for use with MemRegions.
-//===----------------------------------------------------------------------===//
-
-class ElementRegion;
-
-class RegionRawOffset : public std::pair<const MemRegion*, int64_t> {
-private:
- friend class ElementRegion;
-
- RegionRawOffset(const MemRegion* reg, int64_t offset = 0)
- : std::pair<const MemRegion*, int64_t>(reg, offset) {}
-
-public:
- // FIXME: Eventually support symbolic offsets.
- int64_t getByteOffset() const { return second; }
- const MemRegion *getRegion() const { return first; }
-
- void dumpToStream(llvm::raw_ostream& os) const;
- void dump() const;
-};
-
-//===----------------------------------------------------------------------===//
-// MemRegion subclasses.
-//===----------------------------------------------------------------------===//
-
-/// AllocaRegion - A region that represents an untyped blob of bytes created
-/// by a call to 'alloca'.
-class AllocaRegion : public SubRegion {
- friend class MemRegionManager;
-protected:
- unsigned Cnt; // Block counter. Used to distinguish different pieces of
- // memory allocated by alloca at the same call site.
- const Expr* Ex;
-
- AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion)
- : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
-
-public:
-
- const Expr* getExpr() const { return Ex; }
-
- bool isBoundable() const { return true; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex,
- unsigned Cnt, const MemRegion *superRegion);
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == AllocaRegionKind;
- }
-};
-
-/// TypedRegion - An abstract class representing regions that are typed.
-class TypedRegion : public SubRegion {
-protected:
- TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
-
-public:
- virtual QualType getValueType(ASTContext &C) const = 0;
-
- virtual QualType getLocationType(ASTContext& C) const {
- // FIXME: We can possibly optimize this later to cache this value.
- return C.getPointerType(getValueType(C));
- }
-
- QualType getDesugaredValueType(ASTContext& C) const {
- QualType T = getValueType(C);
- return T.getTypePtr() ? T.getDesugaredType() : T;
- }
-
- QualType getDesugaredLocationType(ASTContext& C) const {
- return getLocationType(C).getDesugaredType();
- }
-
- bool isBoundable() const {
- return !getValueType(getContext()).isNull();
- }
-
- static bool classof(const MemRegion* R) {
- unsigned k = R->getKind();
- return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
- }
-};
-
-
-class CodeTextRegion : public TypedRegion {
-protected:
- CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
-public:
- QualType getValueType(ASTContext &C) const {
- // Do not get the object type of a CodeTextRegion.
- assert(0);
- return QualType();
- }
-
- bool isBoundable() const { return false; }
-
- static bool classof(const MemRegion* R) {
- Kind k = R->getKind();
- return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
- }
-};
-
-/// FunctionTextRegion - A region that represents code texts of function.
-class FunctionTextRegion : public CodeTextRegion {
- const FunctionDecl *FD;
-public:
- FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
- : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
-
- QualType getLocationType(ASTContext &C) const {
- return C.getPointerType(FD->getType());
- }
-
- const FunctionDecl *getDecl() const {
- return FD;
- }
-
- virtual void dumpToStream(llvm::raw_ostream& os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
- const MemRegion*);
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == FunctionTextRegionKind;
- }
-};
-
-
-/// BlockTextRegion - A region that represents code texts of blocks (closures).
-/// Blocks are represented with two kinds of regions. BlockTextRegions
-/// represent the "code", while BlockDataRegions represent instances of blocks,
-/// which correspond to "code+data". The distinction is important, because
-/// like a closure a block captures the values of externally referenced
-/// variables.
-class BlockTextRegion : public CodeTextRegion {
- friend class MemRegionManager;
-
- const BlockDecl *BD;
- AnalysisContext *AC;
- CanQualType locTy;
-
- BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
- AnalysisContext *ac, const MemRegion* sreg)
- : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
-
-public:
- QualType getLocationType(ASTContext &C) const {
- return locTy;
- }
-
- const BlockDecl *getDecl() const {
- return BD;
- }
-
- AnalysisContext *getAnalysisContext() const { return AC; }
-
- virtual void dumpToStream(llvm::raw_ostream& os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
- CanQualType, const AnalysisContext*,
- const MemRegion*);
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == BlockTextRegionKind;
- }
-};
-
-/// BlockDataRegion - A region that represents a block instance.
-/// Blocks are represented with two kinds of regions. BlockTextRegions
-/// represent the "code", while BlockDataRegions represent instances of blocks,
-/// which correspond to "code+data". The distinction is important, because
-/// like a closure a block captures the values of externally referenced
-/// variables.
-/// BlockDataRegion - A region that represents code texts of blocks (closures).
-class BlockDataRegion : public SubRegion {
- friend class MemRegionManager;
- const BlockTextRegion *BC;
- const LocationContext *LC; // Can be null */
- void *ReferencedVars;
-
- BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
- const MemRegion *sreg)
- : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
-
-public:
- const BlockTextRegion *getCodeRegion() const { return BC; }
-
- const BlockDecl *getDecl() const { return BC->getDecl(); }
-
- class referenced_vars_iterator {
- const MemRegion * const *R;
- public:
- explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
-
- operator const MemRegion * const *() const {
- return R;
- }
-
- const VarRegion* operator*() const {
- return cast<VarRegion>(*R);
- }
-
- bool operator==(const referenced_vars_iterator &I) const {
- return I.R == R;
- }
- bool operator!=(const referenced_vars_iterator &I) const {
- return I.R != R;
- }
- referenced_vars_iterator& operator++() {
- ++R;
- return *this;
- }
- };
-
- referenced_vars_iterator referenced_vars_begin() const;
- referenced_vars_iterator referenced_vars_end() const;
-
- virtual void dumpToStream(llvm::raw_ostream& os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
- const LocationContext *, const MemRegion *);
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == BlockDataRegionKind;
- }
-private:
- void LazyInitializeReferencedVars();
-};
-
-/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
-/// clases, SymbolicRegion represents a region that serves as an alias for
-/// either a real region, a NULL pointer, etc. It essentially is used to
-/// map the concept of symbolic values into the domain of regions. Symbolic
-/// regions do not need to be typed.
-class SymbolicRegion : public SubRegion {
-protected:
- const SymbolRef sym;
-
-public:
- SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
- : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
-
- SymbolRef getSymbol() const {
- return sym;
- }
-
- bool isBoundable() const { return true; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- SymbolRef sym,
- const MemRegion* superRegion);
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == SymbolicRegionKind;
- }
-};
-
-/// StringRegion - Region associated with a StringLiteral.
-class StringRegion : public TypedRegion {
- friend class MemRegionManager;
- const StringLiteral* Str;
-protected:
-
- StringRegion(const StringLiteral* str, const MemRegion* sreg)
- : TypedRegion(sreg, StringRegionKind), Str(str) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const StringLiteral* Str,
- const MemRegion* superRegion);
-
-public:
-
- const StringLiteral* getStringLiteral() const { return Str; }
-
- QualType getValueType(ASTContext& C) const {
- return Str->getType();
- }
-
- bool isBoundable() const { return false; }
-
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ProfileRegion(ID, Str, superRegion);
- }
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == StringRegionKind;
- }
-};
-
-/// CompoundLiteralRegion - A memory region representing a compound literal.
-/// Compound literals are essentially temporaries that are stack allocated
-/// or in the global constant pool.
-class CompoundLiteralRegion : public TypedRegion {
-private:
- friend class MemRegionManager;
- const CompoundLiteralExpr* CL;
-
- CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg)
- : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const CompoundLiteralExpr* CL,
- const MemRegion* superRegion);
-public:
- QualType getValueType(ASTContext& C) const {
- return C.getCanonicalType(CL->getType());
- }
-
- bool isBoundable() const { return !CL->isFileScope(); }
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- const CompoundLiteralExpr* getLiteralExpr() const { return CL; }
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == CompoundLiteralRegionKind;
- }
-};
-
-class DeclRegion : public TypedRegion {
-protected:
- const Decl* D;
-
- DeclRegion(const Decl* d, const MemRegion* sReg, Kind k)
- : TypedRegion(sReg, k), D(d) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
- const MemRegion* superRegion, Kind k);
-
-public:
- const Decl* getDecl() const { return D; }
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static bool classof(const MemRegion* R) {
- unsigned k = R->getKind();
- return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
- }
-};
-
-class VarRegion : public DeclRegion {
- friend class MemRegionManager;
-
- // Constructors and private methods.
- VarRegion(const VarDecl* vd, const MemRegion* sReg)
- : DeclRegion(vd, sReg, VarRegionKind) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
- const MemRegion *superRegion) {
- DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
-public:
- const VarDecl *getDecl() const { return cast<VarDecl>(D); }
-
- const StackFrameContext *getStackFrame() const;
-
- QualType getValueType(ASTContext& C) const {
- // FIXME: We can cache this if needed.
- return C.getCanonicalType(getDecl()->getType());
- }
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == VarRegionKind;
- }
-};
-
-/// CXXThisRegion - Represents the region for the implicit 'this' parameter
-/// in a call to a C++ method. This region doesn't represent the object
-/// referred to by 'this', but rather 'this' itself.
-class CXXThisRegion : public TypedRegion {
- friend class MemRegionManager;
- CXXThisRegion(const PointerType *thisPointerTy,
- const MemRegion *sReg)
- : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID &ID,
- const PointerType *PT,
- const MemRegion *sReg);
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
-public:
- QualType getValueType(ASTContext &C) const {
- return QualType(ThisPointerTy, 0);
- }
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == CXXThisRegionKind;
- }
-
-private:
- const PointerType *ThisPointerTy;
-};
-
-class FieldRegion : public DeclRegion {
- friend class MemRegionManager;
-
- FieldRegion(const FieldDecl* fd, const MemRegion* sReg)
- : DeclRegion(fd, sReg, FieldRegionKind) {}
-
-public:
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
-
- QualType getValueType(ASTContext& C) const {
- // FIXME: We can cache this if needed.
- return C.getCanonicalType(getDecl()->getType());
- }
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
- }
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == FieldRegionKind;
- }
-};
-
-class ObjCIvarRegion : public DeclRegion {
-
- friend class MemRegionManager;
-
- ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg)
- : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
- }
-
-public:
- const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
- QualType getValueType(ASTContext&) const { return getDecl()->getType(); }
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == ObjCIvarRegionKind;
- }
-};
-
-class ElementRegion : public TypedRegion {
- friend class MemRegionManager;
-
- QualType ElementType;
- SVal Index;
-
- ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg)
- : TypedRegion(sReg, ElementRegionKind),
- ElementType(elementType), Index(Idx) {
- assert((!isa<nonloc::ConcreteInt>(&Idx) ||
- cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
- "The index must be signed");
- }
-
- static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
- SVal Idx, const MemRegion* superRegion);
-
-public:
-
- SVal getIndex() const { return Index; }
-
- QualType getValueType(ASTContext&) const {
- return ElementType;
- }
-
- QualType getElementType() const {
- return ElementType;
- }
-
- RegionRawOffset getAsRawOffset() const;
-
- void dumpToStream(llvm::raw_ostream& os) const;
-
- void Profile(llvm::FoldingSetNodeID& ID) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == ElementRegionKind;
- }
-};
-
-// C++ temporary object associated with an expression.
-class CXXObjectRegion : public TypedRegion {
- friend class MemRegionManager;
-
- Expr const *Ex;
-
- CXXObjectRegion(Expr const *E, MemRegion const *sReg)
- : TypedRegion(sReg, CXXObjectRegionKind), Ex(E) {}
-
- static void ProfileRegion(llvm::FoldingSetNodeID &ID,
- Expr const *E, const MemRegion *sReg);
-
-public:
- QualType getValueType(ASTContext& C) const {
- return Ex->getType();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const;
-
- static bool classof(const MemRegion* R) {
- return R->getKind() == CXXObjectRegionKind;
- }
-};
-
-template<typename RegionTy>
-const RegionTy* MemRegion::getAs() const {
- if (const RegionTy* RT = dyn_cast<RegionTy>(this))
- return RT;
-
- return NULL;
-}
-
-//===----------------------------------------------------------------------===//
-// MemRegionManager - Factory object for creating regions.
-//===----------------------------------------------------------------------===//
-
-class MemRegionManager {
- ASTContext &C;
- llvm::BumpPtrAllocator& A;
- llvm::FoldingSet<MemRegion> Regions;
-
- GlobalsSpaceRegion *globals;
-
- const StackFrameContext *cachedStackLocalsFrame;
- StackLocalsSpaceRegion *cachedStackLocalsRegion;
-
- const StackFrameContext *cachedStackArgumentsFrame;
- StackArgumentsSpaceRegion *cachedStackArgumentsRegion;
-
- HeapSpaceRegion *heap;
- UnknownSpaceRegion *unknown;
- MemSpaceRegion *code;
-
-public:
- MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), globals(0),
- cachedStackLocalsFrame(0), cachedStackLocalsRegion(0),
- cachedStackArgumentsFrame(0), cachedStackArgumentsRegion(0),
- heap(0), unknown(0), code(0) {}
-
- ~MemRegionManager();
-
- ASTContext &getContext() { return C; }
-
- llvm::BumpPtrAllocator &getAllocator() { return A; }
-
- /// getStackLocalsRegion - Retrieve the memory region associated with the
- /// specified stack frame.
- const StackLocalsSpaceRegion *
- getStackLocalsRegion(const StackFrameContext *STC);
-
- /// getStackArgumentsRegion - Retrieve the memory region associated with
- /// function/method arguments of the specified stack frame.
- const StackArgumentsSpaceRegion *
- getStackArgumentsRegion(const StackFrameContext *STC);
-
- /// getGlobalsRegion - Retrieve the memory region associated with
- /// all global variables.
- const GlobalsSpaceRegion *getGlobalsRegion();
-
- /// getHeapRegion - Retrieve the memory region associated with the
- /// generic "heap".
- const HeapSpaceRegion *getHeapRegion();
-
- /// getUnknownRegion - Retrieve the memory region associated with unknown
- /// memory space.
- const MemSpaceRegion *getUnknownRegion();
-
- const MemSpaceRegion *getCodeRegion();
-
- /// getAllocaRegion - Retrieve a region associated with a call to alloca().
- const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt,
- const LocationContext *LC);
-
- /// getCompoundLiteralRegion - Retrieve the region associated with a
- /// given CompoundLiteral.
- const CompoundLiteralRegion*
- getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
- const LocationContext *LC);
-
- /// getCXXThisRegion - Retrieve the [artifical] region associated with the
- /// parameter 'this'.
- const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
- const LocationContext *LC);
-
- /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
- const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
-
- const StringRegion* getStringRegion(const StringLiteral* Str);
-
- /// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl and LocationContext.
- const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
-
- /// getVarRegion - Retrieve or create the memory region associated with
- /// a specified VarDecl and super region.
- const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
-
- /// getElementRegion - Retrieve the memory region associated with the
- /// associated element type, index, and super region.
- const ElementRegion *getElementRegion(QualType elementType, SVal Idx,
- const MemRegion *superRegion,
- ASTContext &Ctx);
-
- const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
- const MemRegion *superRegion) {
- return getElementRegion(ER->getElementType(), ER->getIndex(),
- superRegion, ER->getContext());
- }
-
- /// getFieldRegion - Retrieve or create the memory region associated with
- /// a specified FieldDecl. 'superRegion' corresponds to the containing
- /// memory region (which typically represents the memory representing
- /// a structure or class).
- const FieldRegion *getFieldRegion(const FieldDecl* fd,
- const MemRegion* superRegion);
-
- const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
- const MemRegion *superRegion) {
- return getFieldRegion(FR->getDecl(), superRegion);
- }
-
- /// getObjCIvarRegion - Retrieve or create the memory region associated with
- /// a specified Objective-c instance variable. 'superRegion' corresponds
- /// to the containing region (which typically represents the Objective-C
- /// object).
- const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
- const MemRegion* superRegion);
-
- const CXXObjectRegion *getCXXObjectRegion(Expr const *Ex,
- LocationContext const *LC);
-
- const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
- const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
- CanQualType locTy,
- AnalysisContext *AC);
-
- /// getBlockDataRegion - Get the memory region associated with an instance
- /// of a block. Unlike many other MemRegions, the LocationContext*
- /// argument is allowed to be NULL for cases where we have no known
- /// context.
- const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
- const LocationContext *lc = NULL);
-
- bool isGlobalsRegion(const MemRegion* R) {
- assert(R);
- return R == globals;
- }
-
-private:
- template <typename RegionTy, typename A1>
- RegionTy* getRegion(const A1 a1);
-
- template <typename RegionTy, typename A1>
- RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
-
- template <typename RegionTy, typename A1, typename A2>
- RegionTy* getRegion(const A1 a1, const A2 a2);
-
- template <typename RegionTy, typename A1, typename A2>
- RegionTy* getSubRegion(const A1 a1, const A2 a2,
- const MemRegion* superRegion);
-
- template <typename RegionTy, typename A1, typename A2, typename A3>
- RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
- const MemRegion* superRegion);
-
- template <typename REG>
- const REG* LazyAllocate(REG*& region);
-
- template <typename REG, typename ARG>
- const REG* LazyAllocate(REG*& region, ARG a);
-};
-
-//===----------------------------------------------------------------------===//
-// Out-of-line member definitions.
-//===----------------------------------------------------------------------===//
-
-inline ASTContext& MemRegion::getContext() const {
- return getMemRegionManager()->getContext();
-}
-
-} // end clang namespace
-
-//===----------------------------------------------------------------------===//
-// Pretty-printing regions.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-static inline raw_ostream& operator<<(raw_ostream& os,
- const clang::MemRegion* R) {
- R->dumpToStream(os);
- return os;
-}
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h
deleted file mode 100644
index 9206817989db..000000000000
--- a/include/clang/Analysis/PathSensitive/SVals.h
+++ /dev/null
@@ -1,499 +0,0 @@
-//== SVals.h - Abstract Values for Static Analysis ---------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines SVal, Loc, and NonLoc, classes that represent
-// abstract r-values for use with path-sensitive value tracking.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
-#define LLVM_CLANG_ANALYSIS_RVALUE_H
-
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/ADT/ImmutableList.h"
-
-namespace llvm {
- class raw_ostream;
-}
-
-//==------------------------------------------------------------------------==//
-// Base SVal types.
-//==------------------------------------------------------------------------==//
-
-namespace clang {
-
-class CompoundValData;
-class LazyCompoundValData;
-class GRState;
-class BasicValueFactory;
-class MemRegion;
-class TypedRegion;
-class MemRegionManager;
-class GRStateManager;
-class ValueManager;
-
-class SVal {
-public:
- enum BaseKind { UndefinedKind, UnknownKind, LocKind, NonLocKind };
- enum { BaseBits = 2, BaseMask = 0x3 };
-
-protected:
- void* Data;
- unsigned Kind;
-
-protected:
- SVal(const void* d, bool isLoc, unsigned ValKind)
- : Data(const_cast<void*>(d)),
- Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
-
- explicit SVal(BaseKind k, void* D = NULL)
- : Data(D), Kind(k) {}
-
-public:
- SVal() : Data(0), Kind(0) {}
- ~SVal() {}
-
- /// BufferTy - A temporary buffer to hold a set of SVals.
- typedef llvm::SmallVector<SVal,5> BufferTy;
-
- inline unsigned getRawKind() const { return Kind; }
- inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
- inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
-
- inline void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned) getRawKind());
- ID.AddPointer(reinterpret_cast<void*>(Data));
- }
-
- inline bool operator==(const SVal& R) const {
- return getRawKind() == R.getRawKind() && Data == R.Data;
- }
-
- inline bool operator!=(const SVal& R) const {
- return !(*this == R);
- }
-
- inline bool isUnknown() const {
- return getRawKind() == UnknownKind;
- }
-
- inline bool isUndef() const {
- return getRawKind() == UndefinedKind;
- }
-
- inline bool isUnknownOrUndef() const {
- return getRawKind() <= UnknownKind;
- }
-
- inline bool isValid() const {
- return getRawKind() > UnknownKind;
- }
-
- bool isConstant() const;
-
- bool isZeroConstant() const;
-
- /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
- bool hasConjuredSymbol() const;
-
- /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
- /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
- /// Otherwise return 0.
- const FunctionDecl* getAsFunctionDecl() const;
-
- /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
- /// wraps a symbol, return that SymbolRef. Otherwise return a SymbolData*
- SymbolRef getAsLocSymbol() const;
-
- /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
- /// Otherwise return a SymbolRef where 'isValid()' returns false.
- SymbolRef getAsSymbol() const;
-
- /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
- /// return that expression. Otherwise return NULL.
- const SymExpr *getAsSymbolicExpression() const;
-
- const MemRegion *getAsRegion() const;
-
- void dumpToStream(llvm::raw_ostream& OS) const;
- void dump() const;
-
- // Iterators.
- class symbol_iterator {
- llvm::SmallVector<const SymExpr*, 5> itr;
- void expand();
- public:
- symbol_iterator() {}
- symbol_iterator(const SymExpr* SE);
-
- symbol_iterator& operator++();
- SymbolRef operator*();
-
- bool operator==(const symbol_iterator& X) const;
- bool operator!=(const symbol_iterator& X) const;
- };
-
- symbol_iterator symbol_begin() const {
- const SymExpr *SE = getAsSymbolicExpression();
- if (SE)
- return symbol_iterator(SE);
- else
- return symbol_iterator();
- }
-
- symbol_iterator symbol_end() const { return symbol_iterator(); }
-
- // Implement isa<T> support.
- static inline bool classof(const SVal*) { return true; }
-};
-
-
-class UndefinedVal : public SVal {
-public:
- UndefinedVal() : SVal(UndefinedKind) {}
- UndefinedVal(void* D) : SVal(UndefinedKind, D) {}
-
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == UndefinedKind;
- }
-
- void* getData() const { return Data; }
-};
-
-class DefinedOrUnknownSVal : public SVal {
-private:
- // Do not implement. We want calling these methods to be a compiler
- // error since they are tautologically false.
- bool isUndef() const;
- bool isValid() const;
-
-protected:
- explicit DefinedOrUnknownSVal(const void* d, bool isLoc, unsigned ValKind)
- : SVal(d, isLoc, ValKind) {}
-
- explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
- : SVal(k, D) {}
-
-public:
- // Implement isa<T> support.
- static inline bool classof(const SVal *V) {
- return !V->isUndef();
- }
-};
-
-class UnknownVal : public DefinedOrUnknownSVal {
-public:
- UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
-
- static inline bool classof(const SVal *V) {
- return V->getBaseKind() == UnknownKind;
- }
-};
-
-class DefinedSVal : public DefinedOrUnknownSVal {
-private:
- // Do not implement. We want calling these methods to be a compiler
- // error since they are tautologically true/false.
- bool isUnknown() const;
- bool isUnknownOrUndef() const;
- bool isValid() const;
-protected:
- DefinedSVal(const void* d, bool isLoc, unsigned ValKind)
- : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
-public:
- // Implement isa<T> support.
- static inline bool classof(const SVal *V) {
- return !V->isUnknownOrUndef();
- }
-};
-
-class NonLoc : public DefinedSVal {
-protected:
- NonLoc(unsigned SubKind, const void* d) : DefinedSVal(d, false, SubKind) {}
-
-public:
- void dumpToStream(llvm::raw_ostream& Out) const;
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind;
- }
-};
-
-class Loc : public DefinedSVal {
-protected:
- Loc(unsigned SubKind, const void* D)
- : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
-
-public:
- void dumpToStream(llvm::raw_ostream& Out) const;
-
- Loc(const Loc& X) : DefinedSVal(X.Data, true, X.getSubKind()) {}
- Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind;
- }
-
- static inline bool IsLocType(QualType T) {
- return T->isAnyPointerType() || T->isBlockPointerType() ||
- T->isReferenceType();
- }
-};
-
-//==------------------------------------------------------------------------==//
-// Subclasses of NonLoc.
-//==------------------------------------------------------------------------==//
-
-namespace nonloc {
-
-enum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
- LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
-
-class SymbolVal : public NonLoc {
-public:
- SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
-
- SymbolRef getSymbol() const {
- return (const SymbolData*) Data;
- }
-
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == SymbolValKind;
- }
-
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == SymbolValKind;
- }
-};
-
-class SymExprVal : public NonLoc {
-public:
- SymExprVal(const SymExpr *SE)
- : NonLoc(SymExprValKind, reinterpret_cast<const void*>(SE)) {}
-
- const SymExpr *getSymbolicExpression() const {
- return reinterpret_cast<SymExpr*>(Data);
- }
-
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == SymExprValKind;
- }
-
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == SymExprValKind;
- }
-};
-
-class ConcreteInt : public NonLoc {
-public:
- ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
-
- const llvm::APSInt& getValue() const {
- return *static_cast<llvm::APSInt*>(Data);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- SVal evalBinOp(ValueManager &ValMgr, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
- ConcreteInt evalComplement(ValueManager &ValMgr) const;
-
- ConcreteInt evalMinus(ValueManager &ValMgr) const;
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == ConcreteIntKind;
- }
-
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == ConcreteIntKind;
- }
-};
-
-class LocAsInteger : public NonLoc {
- friend class clang::ValueManager;
-
- LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
- NonLoc(LocAsIntegerKind, &data) {
- assert (isa<Loc>(data.first));
- }
-
-public:
-
- Loc getLoc() const {
- return cast<Loc>(((std::pair<SVal, uintptr_t>*) Data)->first);
- }
-
- const Loc& getPersistentLoc() const {
- const SVal& V = ((std::pair<SVal, uintptr_t>*) Data)->first;
- return cast<Loc>(V);
- }
-
- unsigned getNumBits() const {
- return ((std::pair<SVal, unsigned>*) Data)->second;
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == LocAsIntegerKind;
- }
-
- static inline bool classof(const NonLoc* V) {
- return V->getSubKind() == LocAsIntegerKind;
- }
-};
-
-class CompoundVal : public NonLoc {
- friend class clang::ValueManager;
-
- CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
-
-public:
- const CompoundValData* getValue() const {
- return static_cast<CompoundValData*>(Data);
- }
-
- typedef llvm::ImmutableList<SVal>::iterator iterator;
- iterator begin() const;
- iterator end() const;
-
- static bool classof(const SVal* V) {
- return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
- }
-
- static bool classof(const NonLoc* V) {
- return V->getSubKind() == CompoundValKind;
- }
-};
-
-class LazyCompoundVal : public NonLoc {
- friend class clang::ValueManager;
-
- LazyCompoundVal(const LazyCompoundValData *D)
- : NonLoc(LazyCompoundValKind, D) {}
-public:
- const LazyCompoundValData *getCVData() const {
- return static_cast<const LazyCompoundValData*>(Data);
- }
- const GRState *getState() const;
- const TypedRegion *getRegion() const;
-
- static bool classof(const SVal *V) {
- return V->getBaseKind() == NonLocKind &&
- V->getSubKind() == LazyCompoundValKind;
- }
- static bool classof(const NonLoc *V) {
- return V->getSubKind() == LazyCompoundValKind;
- }
-};
-
-} // end namespace clang::nonloc
-
-//==------------------------------------------------------------------------==//
-// Subclasses of Loc.
-//==------------------------------------------------------------------------==//
-
-namespace loc {
-
-enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind };
-
-class GotoLabel : public Loc {
-public:
- GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
-
- LabelStmt* getLabel() const {
- return static_cast<LabelStmt*>(Data);
- }
-
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind &&
- V->getSubKind() == GotoLabelKind;
- }
-
- static inline bool classof(const Loc* V) {
- return V->getSubKind() == GotoLabelKind;
- }
-};
-
-
-class MemRegionVal : public Loc {
-public:
- MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
-
- const MemRegion* getRegion() const {
- return static_cast<MemRegion*>(Data);
- }
-
- const MemRegion* StripCasts() const;
-
- template <typename REGION>
- const REGION* getRegionAs() const {
- return llvm::dyn_cast<REGION>(getRegion());
- }
-
- inline bool operator==(const MemRegionVal& R) const {
- return getRegion() == R.getRegion();
- }
-
- inline bool operator!=(const MemRegionVal& R) const {
- return getRegion() != R.getRegion();
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind &&
- V->getSubKind() == MemRegionKind;
- }
-
- static inline bool classof(const Loc* V) {
- return V->getSubKind() == MemRegionKind;
- }
-};
-
-class ConcreteInt : public Loc {
-public:
- ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
-
- const llvm::APSInt& getValue() const {
- return *static_cast<llvm::APSInt*>(Data);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- SVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
- // Implement isa<T> support.
- static inline bool classof(const SVal* V) {
- return V->getBaseKind() == LocKind &&
- V->getSubKind() == ConcreteIntKind;
- }
-
- static inline bool classof(const Loc* V) {
- return V->getSubKind() == ConcreteIntKind;
- }
-};
-
-} // end clang::loc namespace
-} // end clang namespace
-
-namespace llvm {
-static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
- clang::SVal V) {
- V.dumpToStream(os);
- return os;
-}
-} // end llvm namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/SValuator.h b/include/clang/Analysis/PathSensitive/SValuator.h
deleted file mode 100644
index 4a4b502c6271..000000000000
--- a/include/clang/Analysis/PathSensitive/SValuator.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// SValuator.h - Construction of SVals from evaluating expressions -*- C++ -*---
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines SValuator, a class that defines the interface for
-// "symbolical evaluators" which construct an SVal from an expression.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_SVALUATOR
-#define LLVM_CLANG_ANALYSIS_SVALUATOR
-
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-
-namespace clang {
-
-class GRState;
-class ValueManager;
-
-class SValuator {
- friend class ValueManager;
-protected:
- ValueManager &ValMgr;
-
-public:
- // FIXME: Make these protected again one RegionStoreManager correctly
- // handles loads from differening bound value types.
- virtual SVal EvalCastNL(NonLoc val, QualType castTy) = 0;
- virtual SVal EvalCastL(Loc val, QualType castTy) = 0;
-
-public:
- SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
- virtual ~SValuator() {}
-
- template <typename T>
- class GenericCastResult : public std::pair<const GRState *, T> {
- public:
- const GRState *getState() const { return this->first; }
- T getSVal() const { return this->second; }
- GenericCastResult(const GRState *s, T v)
- : std::pair<const GRState*,T>(s, v) {}
- };
-
- class CastResult : public GenericCastResult<SVal> {
- public:
- CastResult(const GRState *s, SVal v) : GenericCastResult<SVal>(s, v) {}
- };
-
- class DefinedOrUnknownCastResult :
- public GenericCastResult<DefinedOrUnknownSVal> {
- public:
- DefinedOrUnknownCastResult(const GRState *s, DefinedOrUnknownSVal v)
- : GenericCastResult<DefinedOrUnknownSVal>(s, v) {}
- };
-
- CastResult EvalCast(SVal V, const GRState *ST,
- QualType castTy, QualType originalType);
-
- DefinedOrUnknownCastResult EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
- QualType castTy, QualType originalType);
-
- virtual SVal EvalMinus(NonLoc val) = 0;
-
- virtual SVal EvalComplement(NonLoc val) = 0;
-
- virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode Op,
- NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
-
- virtual SVal EvalBinOpLL(BinaryOperator::Opcode Op, Loc lhs, Loc rhs,
- QualType resultTy) = 0;
-
- virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode Op,
- Loc lhs, NonLoc rhs, QualType resultTy) = 0;
-
- SVal EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
- SVal L, SVal R, QualType T);
-
- DefinedOrUnknownSVal EvalEQ(const GRState *ST, DefinedOrUnknownSVal L,
- DefinedOrUnknownSVal R);
-};
-
-SValuator* CreateSimpleSValuator(ValueManager &valMgr);
-
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
deleted file mode 100644
index 5606df0014f0..000000000000
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//== Store.h - Interface for maps from Locations to Values ------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defined the types Store and StoreManager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_STORE_H
-#define LLVM_CLANG_ANALYSIS_STORE_H
-
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/Analysis/PathSensitive/ValueManager.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-typedef const void* Store;
-
-class GRState;
-class GRStateManager;
-class Stmt;
-class Expr;
-class ObjCIvarDecl;
-class SubRegionMap;
-class StackFrameContext;
-
-class StoreManager {
-protected:
- ValueManager &ValMgr;
- GRStateManager &StateMgr;
-
- /// MRMgr - Manages region objects associated with this StoreManager.
- MemRegionManager &MRMgr;
-
- StoreManager(GRStateManager &stateMgr);
-
-public:
- virtual ~StoreManager() {}
-
- /// Return the value bound to specified location in a given state.
- /// \param[in] state The analysis state.
- /// \param[in] loc The symbolic memory location.
- /// \param[in] T An optional type that provides a hint indicating the
- /// expected type of the returned value. This is used if the value is
- /// lazily computed.
- /// \return The value bound to the location \c loc.
- virtual SValuator::CastResult Retrieve(const GRState *state, Loc loc,
- QualType T = QualType()) = 0;
-
- /// Return a state with the specified value bound to the given location.
- /// \param[in] state The analysis state.
- /// \param[in] loc The symbolic memory location.
- /// \param[in] val The value to bind to location \c loc.
- /// \return A pointer to a GRState object that contains the same bindings as
- /// \c state with the addition of having the value specified by \c val bound
- /// to the location given for \c loc.
- virtual const GRState *Bind(const GRState *state, Loc loc, SVal val) = 0;
-
- virtual Store Remove(Store St, Loc L) = 0;
-
- /// BindCompoundLiteral - Return the store that has the bindings currently
- /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
- /// for the compound literal and 'BegInit' and 'EndInit' represent an
- /// array of initializer values.
- virtual const GRState *BindCompoundLiteral(const GRState *state,
- const CompoundLiteralExpr* cl,
- const LocationContext *LC,
- SVal v) = 0;
-
- /// getInitialStore - Returns the initial "empty" store representing the
- /// value bindings upon entry to an analyzed function.
- virtual Store getInitialStore(const LocationContext *InitLoc) = 0;
-
- /// getRegionManager - Returns the internal RegionManager object that is
- /// used to query and manipulate MemRegion objects.
- MemRegionManager& getRegionManager() { return MRMgr; }
-
- /// getSubRegionMap - Returns an opaque map object that clients can query
- /// to get the subregions of a given MemRegion object. It is the
- // caller's responsibility to 'delete' the returned map.
- virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0;
-
- virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) = 0;
-
- virtual SVal getLValueString(const StringLiteral* sl) = 0;
-
- SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl,
- const LocationContext *LC);
-
- virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) = 0;
-
- virtual SVal getLValueField(const FieldDecl* D, SVal Base) = 0;
-
- virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
-
- // FIXME: Make out-of-line.
- virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
- const MemRegion *region,
- QualType EleTy) {
- return UnknownVal();
- }
-
- /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
- /// conversions between arrays and pointers.
- virtual SVal ArrayToPointer(Loc Array) = 0;
-
- class CastResult {
- const GRState *state;
- const MemRegion *region;
- public:
- const GRState *getState() const { return state; }
- const MemRegion* getRegion() const { return region; }
- CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){}
- };
-
- /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
- /// a MemRegion* to a specific location type. 'R' is the region being
- /// casted and 'CastToTy' the result type of the cast.
- const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
-
- /// EvalBinOp - Perform pointer arithmetic.
- virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,
- Loc lhs, NonLoc rhs, QualType resultTy) {
- return UnknownVal();
- }
-
- virtual void RemoveDeadBindings(GRState &state, Stmt* Loc,
- SymbolReaper& SymReaper,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
-
- virtual const GRState *BindDecl(const GRState *ST, const VarRegion *VR,
- SVal initVal) = 0;
-
- virtual const GRState *BindDeclWithNoInit(const GRState *ST,
- const VarRegion *VR) = 0;
-
- typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
-
- virtual const GRState *InvalidateRegion(const GRState *state,
- const MemRegion *R,
- const Expr *E, unsigned Count,
- InvalidatedSymbols *IS) = 0;
-
- virtual const GRState *InvalidateRegions(const GRState *state,
- const MemRegion * const *Begin,
- const MemRegion * const *End,
- const Expr *E, unsigned Count,
- InvalidatedSymbols *IS);
-
- // FIXME: Make out-of-line.
- virtual const GRState *setExtent(const GRState *state,
- const MemRegion *region, SVal extent) {
- return state;
- }
-
- /// EnterStackFrame - Let the StoreManager to do something when execution
- /// engine is about to execute into a callee.
- virtual const GRState *EnterStackFrame(const GRState *state,
- const StackFrameContext *frame) {
- return state;
- }
-
- virtual void print(Store store, llvm::raw_ostream& Out,
- const char* nl, const char *sep) = 0;
-
- class BindingsHandler {
- public:
- virtual ~BindingsHandler();
- virtual bool HandleBinding(StoreManager& SMgr, Store store,
- const MemRegion *region, SVal val) = 0;
- };
-
- /// iterBindings - Iterate over the bindings in the Store.
- virtual void iterBindings(Store store, BindingsHandler& f) = 0;
-
-protected:
- const MemRegion *MakeElementRegion(const MemRegion *Base,
- QualType pointeeTy, uint64_t index = 0);
-
- /// CastRetrievedVal - Used by subclasses of StoreManager to implement
- /// implicit casts that arise from loads from regions that are reinterpreted
- /// as another region.
- SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy,
- bool performTestOnly = true);
-};
-
-// FIXME: Do we still need this?
-/// SubRegionMap - An abstract interface that represents a queryable map
-/// between MemRegion objects and their subregions.
-class SubRegionMap {
-public:
- virtual ~SubRegionMap() {}
-
- class Visitor {
- public:
- virtual ~Visitor() {}
- virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
- };
-
- virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0;
-};
-
-// FIXME: Do we need to pass GRStateManager anymore?
-StoreManager *CreateBasicStoreManager(GRStateManager& StMgr);
-StoreManager *CreateRegionStoreManager(GRStateManager& StMgr);
-StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr);
-
-} // end clang namespace
-
-#endif
diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h
deleted file mode 100644
index 8eb319647953..000000000000
--- a/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ /dev/null
@@ -1,385 +0,0 @@
-//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines SymbolManager, a class that manages symbolic values
-// created for use by GRExprEngine and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H
-#define LLVM_CLANG_ANALYSIS_SYMMGR_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "llvm/System/DataTypes.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/DenseSet.h"
-
-namespace llvm {
- class raw_ostream;
-}
-
-namespace clang {
- class ASTContext;
- class BasicValueFactory;
- class MemRegion;
- class TypedRegion;
- class VarRegion;
- class StackFrameContext;
-}
-
-namespace clang {
-
-class SymExpr : public llvm::FoldingSetNode {
-public:
- enum Kind { BEGIN_SYMBOLS,
- RegionValueKind, ConjuredKind, DerivedKind,
- END_SYMBOLS,
- SymIntKind, SymSymKind };
-private:
- Kind K;
-
-protected:
- SymExpr(Kind k) : K(k) {}
-
-public:
- virtual ~SymExpr() {}
-
- Kind getKind() const { return K; }
-
- void dump() const;
-
- virtual void dumpToStream(llvm::raw_ostream &os) const = 0;
-
- virtual QualType getType(ASTContext&) const = 0;
- virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr*) { return true; }
-};
-
-typedef unsigned SymbolID;
-
-class SymbolData : public SymExpr {
-private:
- const SymbolID Sym;
-
-protected:
- SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
-
-public:
- virtual ~SymbolData() {}
-
- SymbolID getSymbolID() const { return Sym; }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr* SE) {
- Kind k = SE->getKind();
- return k > BEGIN_SYMBOLS && k < END_SYMBOLS;
- }
-};
-
-typedef const SymbolData* SymbolRef;
-
-class SymbolRegionValue : public SymbolData {
- const MemRegion *R;
- // We may cast the region to another type, so the expected type of the symbol
- // may be different from the region's original type.
- QualType T;
-
-public:
- SymbolRegionValue(SymbolID sym, const MemRegion *r, QualType t = QualType())
- : SymbolData(RegionValueKind, sym), R(r), T(t) {}
-
- const MemRegion* getRegion() const { return R; }
-
- static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R,
- QualType T) {
- profile.AddInteger((unsigned) RegionValueKind);
- profile.AddPointer(R);
- T.Profile(profile);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, R, T);
- }
-
- void dumpToStream(llvm::raw_ostream &os) const;
-
- QualType getType(ASTContext&) const;
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr* SE) {
- return SE->getKind() == RegionValueKind;
- }
-};
-
-class SymbolConjured : public SymbolData {
- const Stmt* S;
- QualType T;
- unsigned Count;
- const void* SymbolTag;
-
-public:
- SymbolConjured(SymbolID sym, const Stmt* s, QualType t, unsigned count,
- const void* symbolTag)
- : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count),
- SymbolTag(symbolTag) {}
-
- const Stmt* getStmt() const { return S; }
- unsigned getCount() const { return Count; }
- const void* getTag() const { return SymbolTag; }
-
- QualType getType(ASTContext&) const;
-
- void dumpToStream(llvm::raw_ostream &os) const;
-
- static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S,
- QualType T, unsigned Count, const void* SymbolTag) {
- profile.AddInteger((unsigned) ConjuredKind);
- profile.AddPointer(S);
- profile.Add(T);
- profile.AddInteger(Count);
- profile.AddPointer(SymbolTag);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, S, T, Count, SymbolTag);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr* SE) {
- return SE->getKind() == ConjuredKind;
- }
-};
-
-class SymbolDerived : public SymbolData {
- SymbolRef parentSymbol;
- const TypedRegion *R;
-
-public:
- SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r)
- : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {}
-
- SymbolRef getParentSymbol() const { return parentSymbol; }
- const TypedRegion *getRegion() const { return R; }
-
- QualType getType(ASTContext&) const;
-
- void dumpToStream(llvm::raw_ostream &os) const;
-
- static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
- const TypedRegion *r) {
- profile.AddInteger((unsigned) DerivedKind);
- profile.AddPointer(r);
- profile.AddPointer(parent);
- }
-
- virtual void Profile(llvm::FoldingSetNodeID& profile) {
- Profile(profile, parentSymbol, R);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr* SE) {
- return SE->getKind() == DerivedKind;
- }
-};
-
-// SymIntExpr - Represents symbolic expression like 'x' + 3.
-class SymIntExpr : public SymExpr {
- const SymExpr *LHS;
- BinaryOperator::Opcode Op;
- const llvm::APSInt& RHS;
- QualType T;
-
-public:
- SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t)
- : SymExpr(SymIntKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
-
- // FIXME: We probably need to make this out-of-line to avoid redundant
- // generation of virtual functions.
- QualType getType(ASTContext& C) const { return T; }
-
- BinaryOperator::Opcode getOpcode() const { return Op; }
-
- void dumpToStream(llvm::raw_ostream &os) const;
-
- const SymExpr *getLHS() const { return LHS; }
- const llvm::APSInt &getRHS() const { return RHS; }
-
- static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
- BinaryOperator::Opcode op, const llvm::APSInt& rhs,
- QualType t) {
- ID.AddInteger((unsigned) SymIntKind);
- ID.AddPointer(lhs);
- ID.AddInteger(op);
- ID.AddPointer(&rhs);
- ID.Add(t);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) {
- Profile(ID, LHS, Op, RHS, T);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr* SE) {
- return SE->getKind() == SymIntKind;
- }
-};
-
-// SymSymExpr - Represents symbolic expression like 'x' + 'y'.
-class SymSymExpr : public SymExpr {
- const SymExpr *LHS;
- BinaryOperator::Opcode Op;
- const SymExpr *RHS;
- QualType T;
-
-public:
- SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
- QualType t)
- : SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
-
- const SymExpr *getLHS() const { return LHS; }
- const SymExpr *getRHS() const { return RHS; }
-
- // FIXME: We probably need to make this out-of-line to avoid redundant
- // generation of virtual functions.
- QualType getType(ASTContext& C) const { return T; }
-
- void dumpToStream(llvm::raw_ostream &os) const;
-
- static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
- BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
- ID.AddInteger((unsigned) SymSymKind);
- ID.AddPointer(lhs);
- ID.AddInteger(op);
- ID.AddPointer(rhs);
- ID.Add(t);
- }
-
- void Profile(llvm::FoldingSetNodeID& ID) {
- Profile(ID, LHS, Op, RHS, T);
- }
-
- // Implement isa<T> support.
- static inline bool classof(const SymExpr* SE) {
- return SE->getKind() == SymSymKind;
- }
-};
-
-class SymbolManager {
- typedef llvm::FoldingSet<SymExpr> DataSetTy;
- DataSetTy DataSet;
- unsigned SymbolCounter;
- llvm::BumpPtrAllocator& BPAlloc;
- BasicValueFactory &BV;
- ASTContext& Ctx;
-
-public:
- SymbolManager(ASTContext& ctx, BasicValueFactory &bv,
- llvm::BumpPtrAllocator& bpalloc)
- : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
-
- ~SymbolManager();
-
- static bool canSymbolicate(QualType T);
-
- /// Make a unique symbol for MemRegion R according to its kind.
- const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R,
- QualType T = QualType());
- const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
- unsigned VisitCount,
- const void* SymbolTag = 0);
-
- const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
- const void* SymbolTag = 0) {
- return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag);
- }
-
- const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
- const TypedRegion *R);
-
- const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t);
-
- const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType t) {
- return getSymIntExpr(&lhs, op, rhs, t);
- }
-
- const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType t);
-
- QualType getType(const SymExpr *SE) const {
- return SE->getType(Ctx);
- }
-
- ASTContext &getContext() { return Ctx; }
- BasicValueFactory &getBasicVals() { return BV; }
-};
-
-class SymbolReaper {
- typedef llvm::DenseSet<SymbolRef> SetTy;
-
- SetTy TheLiving;
- SetTy TheDead;
- LiveVariables& Liveness;
- SymbolManager& SymMgr;
- const StackFrameContext *CurrentStackFrame;
-
-public:
- SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr,
- const StackFrameContext *currentStackFrame)
- : Liveness(liveness), SymMgr(symmgr), CurrentStackFrame(currentStackFrame)
- {}
-
- ~SymbolReaper() {}
-
- bool isLive(SymbolRef sym);
-
- bool isLive(const Stmt* Loc, const Stmt* ExprVal) const {
- return Liveness.isLive(Loc, ExprVal);
- }
-
- bool isLive(const Stmt* Loc, const VarRegion *VR) const;
-
- void markLive(SymbolRef sym);
- bool maybeDead(SymbolRef sym);
-
- typedef SetTy::const_iterator dead_iterator;
- dead_iterator dead_begin() const { return TheDead.begin(); }
- dead_iterator dead_end() const { return TheDead.end(); }
-
- bool hasDeadSymbols() const {
- return !TheDead.empty();
- }
-};
-
-class SymbolVisitor {
-public:
- // VisitSymbol - A visitor method invoked by
- // GRStateManager::scanReachableSymbols. The method returns \c true if
- // symbols should continue be scanned and \c false otherwise.
- virtual bool VisitSymbol(SymbolRef sym) = 0;
- virtual ~SymbolVisitor();
-};
-
-} // end clang namespace
-
-namespace llvm {
-static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os,
- const clang::SymExpr *SE) {
- SE->dumpToStream(os);
- return os;
-}
-} // end llvm namespace
-#endif
diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h
deleted file mode 100644
index 9cec3c421fbe..000000000000
--- a/include/clang/Analysis/PathSensitive/ValueManager.h
+++ /dev/null
@@ -1,208 +0,0 @@
-//== ValueManager.h - Aggregate manager of symbols and SVals ----*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines ValueManager, a class that manages symbolic values
-// and SVals created for use by GRExprEngine and related classes. It
-// wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
-#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
-
-#include "llvm/ADT/OwningPtr.h"
-#include "clang/Analysis/PathSensitive/MemRegion.h"
-#include "clang/Analysis/PathSensitive/SVals.h"
-#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
-#include "clang/Analysis/PathSensitive/SymbolManager.h"
-#include "clang/Analysis/PathSensitive/SValuator.h"
-
-namespace llvm { class BumpPtrAllocator; }
-
-namespace clang {
-
-class GRStateManager;
-
-class ValueManager {
-
- ASTContext &Context;
- BasicValueFactory BasicVals;
-
- /// SymMgr - Object that manages the symbol information.
- SymbolManager SymMgr;
-
- /// SVator - SValuator object that creates SVals from expressions.
- llvm::OwningPtr<SValuator> SVator;
-
- MemRegionManager MemMgr;
-
- GRStateManager &StateMgr;
-
- const QualType ArrayIndexTy;
- const unsigned ArrayIndexWidth;
-
-public:
- ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context,
- GRStateManager &stateMgr)
- : Context(context), BasicVals(context, alloc),
- SymMgr(context, BasicVals, alloc),
- MemMgr(context, alloc), StateMgr(stateMgr),
- ArrayIndexTy(context.IntTy),
- ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {
- // FIXME: Generalize later.
- SVator.reset(clang::CreateSimpleSValuator(*this));
- }
-
- // Accessors to submanagers.
-
- ASTContext &getContext() { return Context; }
- const ASTContext &getContext() const { return Context; }
-
- GRStateManager &getStateManager() { return StateMgr; }
-
- BasicValueFactory &getBasicValueFactory() { return BasicVals; }
- const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
-
- SymbolManager &getSymbolManager() { return SymMgr; }
- const SymbolManager &getSymbolManager() const { return SymMgr; }
-
- SValuator &getSValuator() { return *SVator.get(); }
-
- MemRegionManager &getRegionManager() { return MemMgr; }
- const MemRegionManager &getRegionManager() const { return MemMgr; }
-
- // Forwarding methods to SymbolManager.
-
- const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T,
- unsigned VisitCount,
- const void* SymbolTag = 0) {
- return SymMgr.getConjuredSymbol(E, T, VisitCount, SymbolTag);
- }
-
- const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount,
- const void* SymbolTag = 0) {
- return SymMgr.getConjuredSymbol(E, VisitCount, SymbolTag);
- }
-
- /// makeZeroVal - Construct an SVal representing '0' for the specified type.
- DefinedOrUnknownSVal makeZeroVal(QualType T);
-
- /// getRegionValueSymbolVal - make a unique symbol for value of R.
- DefinedOrUnknownSVal getRegionValueSymbolVal(const MemRegion *R,
- QualType T = QualType());
-
- DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
- const Expr *E, unsigned Count);
- DefinedOrUnknownSVal getConjuredSymbolVal(const void *SymbolTag,
- const Expr *E, QualType T,
- unsigned Count);
-
- DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
- const TypedRegion *R);
-
- DefinedSVal getFunctionPointer(const FunctionDecl *FD);
-
- DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
- const LocationContext *LC);
-
- NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
- return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
- }
-
- NonLoc makeLazyCompoundVal(const GRState *state, const TypedRegion *R) {
- return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(state, R));
- }
-
- NonLoc makeZeroArrayIndex() {
- return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
- }
-
- NonLoc makeArrayIndex(uint64_t idx) {
- return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
- }
-
- SVal convertToArrayIndex(SVal V);
-
- nonloc::ConcreteInt makeIntVal(const IntegerLiteral* I) {
- return nonloc::ConcreteInt(BasicVals.getValue(I->getValue(),
- I->getType()->isUnsignedIntegerType()));
- }
-
- nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
- return nonloc::ConcreteInt(BasicVals.getValue(V));
- }
-
- loc::ConcreteInt makeIntLocVal(const llvm::APSInt &v) {
- return loc::ConcreteInt(BasicVals.getValue(v));
- }
-
- NonLoc makeIntVal(const llvm::APInt& V, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getValue(V, isUnsigned));
- }
-
- DefinedSVal makeIntVal(uint64_t X, QualType T) {
- if (Loc::IsLocType(T))
- return loc::ConcreteInt(BasicVals.getValue(X, T));
-
- return nonloc::ConcreteInt(BasicVals.getValue(X, T));
- }
-
- NonLoc makeIntVal(uint64_t X, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
- }
-
- NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
- }
-
- NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
- return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
- }
-
- NonLoc makeLocAsInteger(Loc V, unsigned Bits) {
- return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(V, Bits));
- }
-
- NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType T);
-
- NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType T);
-
- NonLoc makeTruthVal(bool b, QualType T) {
- return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
- }
-
- NonLoc makeTruthVal(bool b) {
- return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
- }
-
- Loc makeNull() {
- return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
- }
-
- Loc makeLoc(SymbolRef Sym) {
- return loc::MemRegionVal(MemMgr.getSymbolicRegion(Sym));
- }
-
- Loc makeLoc(const MemRegion* R) {
- return loc::MemRegionVal(R);
- }
-
- Loc makeLoc(const AddrLabelExpr* E) {
- return loc::GotoLabel(E->getLabel());
- }
-
- Loc makeLoc(const llvm::APSInt& V) {
- return loc::ConcreteInt(BasicVals.getValue(V));
- }
-};
-} // end clang namespace
-#endif
-
diff --git a/include/clang/Analysis/Support/Optional.h b/include/clang/Analysis/Support/Optional.h
index 40f38be020a9..a4e6d519a04f 100644
--- a/include/clang/Analysis/Support/Optional.h
+++ b/include/clang/Analysis/Support/Optional.h
@@ -20,19 +20,27 @@ namespace clang {
template<typename T>
class Optional {
- const T x;
+ T x;
unsigned hasVal : 1;
public:
- explicit Optional() : hasVal(false) {}
+ explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
+ Optional &operator=(const T &y) {
+ x = y;
+ hasVal = true;
+ return *this;
+ }
+
const T* getPointer() const { assert(hasVal); return &x; }
+ const T& getValue() const { assert(hasVal); return x; }
operator bool() const { return hasVal; }
+ bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
const T& operator*() const { assert(hasVal); return x; }
};