clang  9.0.0
DynamicTypeMap.cpp
Go to the documentation of this file.
1 //===- DynamicTypeMap.cpp - Dynamic Type Info related APIs ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines APIs that track and query dynamic type information. This
10 // information can be used to devirtualize calls during the symbolic execution
11 // or do type checking.
12 //
13 //===----------------------------------------------------------------------===//
14 
17 #include "clang/Basic/LLVM.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cassert>
24 
25 namespace clang {
26 namespace ento {
27 
29  const MemRegion *Reg) {
30  Reg = Reg->StripCasts();
31 
32  // Look up the dynamic type in the GDM.
33  const DynamicTypeInfo *GDMType = State->get<DynamicTypeMap>(Reg);
34  if (GDMType)
35  return *GDMType;
36 
37  // Otherwise, fall back to what we know about the region.
38  if (const auto *TR = dyn_cast<TypedRegion>(Reg))
39  return DynamicTypeInfo(TR->getLocationType(), /*CanBeSub=*/false);
40 
41  if (const auto *SR = dyn_cast<SymbolicRegion>(Reg)) {
42  SymbolRef Sym = SR->getSymbol();
43  return DynamicTypeInfo(Sym->getType());
44  }
45 
46  return {};
47 }
48 
50  DynamicTypeInfo NewTy) {
51  Reg = Reg->StripCasts();
52  ProgramStateRef NewState = State->set<DynamicTypeMap>(Reg, NewTy);
53  assert(NewState);
54  return NewState;
55 }
56 
58  const char *NL, unsigned int Space, bool IsDot) {
59  Indent(Out, Space, IsDot) << "\"dynamic_types\": ";
60 
61  const DynamicTypeMapTy &DTM = State->get<DynamicTypeMap>();
62  if (DTM.isEmpty()) {
63  Out << "null," << NL;
64  return;
65  }
66 
67  ++Space;
68  Out << '[' << NL;
69  for (DynamicTypeMapTy::iterator I = DTM.begin(); I != DTM.end(); ++I) {
70  const MemRegion *MR = I->first;
71  const DynamicTypeInfo &DTI = I->second;
72  Out << "{ \"region\": \"" << MR << "\", \"dyn_type\": ";
73  if (DTI.isValid()) {
74  Out << '\"' << DTI.getType()->getPointeeType().getAsString()
75  << "\", \"sub_classable\": "
76  << (DTI.canBeASubClass() ? "true" : "false");
77  } else {
78  Out << "null"; // Invalid type info
79  }
80  Out << "}";
81 
82  if (std::next(I) != DTM.end())
83  Out << ',';
84  Out << NL;
85  }
86 
87  --Space;
88  Indent(Out, Space, IsDot) << "]," << NL;
89 }
90 
92  static int index = 0;
93  return &index;
94 }
95 
96 } // namespace ento
97 } // namespace clang
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:505
Symbolic value.
Definition: SymExpr.h:29
bool isValid() const
Return false if no dynamic type info is available.
The GDM component containing the dynamic type info.
LineState State
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
virtual QualType getType() const =0
bool canBeASubClass() const
Returns false if the type information is precise (the type T is the only type in the lattice)...
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg, DynamicTypeInfo NewTy)
Set dynamic type information of the region; return the new state.
Dataflow Directional Tag Classes.
llvm::ImmutableMap< const MemRegion *, DynamicTypeInfo > DynamicTypeMapTy
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg)
Get dynamic type information for a region.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:976
const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1196
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\, unsigned int Space=0, bool IsDot=false)
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:20