blob: 8bc0b3b89ef6bc44dc074c09c78400f30ce41b1c [file] [log] [blame]
Ted Kremenek79784522008-01-03 22:12:28 +00001//===-- GRConstantPropagation.cpp --------------------------------*- C++ -*-==//
Ted Kremenek79784522008-01-03 22:12:28 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek7794e2e2008-01-08 00:07:06 +000010// Constant Propagation via Graph Reachability
11//
Ted Kremenek79784522008-01-03 22:12:28 +000012// This files defines a simple analysis that performs path-sensitive
13// constant propagation within a function. An example use of this analysis
14// is to perform simple checks for NULL dereferences.
15//
16//===----------------------------------------------------------------------===//
17
Ted Kremenek4241b3d2008-01-07 19:08:42 +000018#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
Ted Kremenek79784522008-01-03 22:12:28 +000019#include "clang/AST/Expr.h"
20#include "clang/AST/CFG.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/DataTypes.h"
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/APFloat.h"
25#include "llvm/ADT/ImmutableMap.h"
26
27using namespace clang;
28using llvm::APInt;
29using llvm::APFloat;
30using llvm::dyn_cast;
31using llvm::cast;
32
33//===----------------------------------------------------------------------===//
34// ConstV - Represents a variant over APInt, APFloat, and const char
35//===----------------------------------------------------------------------===//
36
37namespace {
38class ConstV {
39 uintptr_t Data;
40public:
41 enum VariantType { VTString = 0x0, VTObjCString = 0x1,
42 VTFloat = 0x2, VTInt = 0x3,
43 Flags = 0x3 };
44
45 ConstV(const StringLiteral* v)
46 : Data(reinterpret_cast<uintptr_t>(v) | VTString) {}
47
48 ConstV(const ObjCStringLiteral* v)
49 : Data(reinterpret_cast<uintptr_t>(v) | VTObjCString) {}
50
51 ConstV(llvm::APInt* v)
52 : Data(reinterpret_cast<uintptr_t>(v) | VTInt) {}
53
54 ConstV(llvm::APFloat* v)
55 : Data(reinterpret_cast<uintptr_t>(v) | VTFloat) {}
56
57
58 inline void* getData() const { return (void*) (Data & ~Flags); }
59 inline VariantType getVT() const { return (VariantType) (Data & Flags); }
60
61 inline void Profile(llvm::FoldingSetNodeID& ID) const {
62 ID.AddPointer(getData());
63 }
64};
65} // end anonymous namespace
66
67// Overload machinery for casting from ConstV to contained classes.
68
69namespace llvm {
70
71#define CV_OBJ_CAST(CLASS,FLAG)\
72template<> inline bool isa<CLASS,ConstV>(const ConstV& V) {\
73 return V.getVT() == FLAG;\
74}\
75\
76template <> struct cast_retty_impl<CLASS, ConstV> {\
77 typedef const CLASS* ret_type;\
78};
79
80CV_OBJ_CAST(APInt,ConstV::VTInt)
81CV_OBJ_CAST(APFloat,ConstV::VTFloat)
82CV_OBJ_CAST(StringLiteral,ConstV::VTString)
83CV_OBJ_CAST(ObjCStringLiteral,ConstV::VTObjCString)
84
85#undef CV_OBJ_CAST
86
87template <> struct simplify_type<ConstV> {
88 typedef void* SimpleType;
89 static SimpleType getSimplifiedValue(const ConstV &Val) {
90 return Val.getData();
91 }
92};
93
94} // end llvm namespace
95
Ted Kremenek79784522008-01-03 22:12:28 +000096