1 //===-- Transfer.cpp --------------------------------------------*- C++ -*-===//
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 transfer functions that evaluate program statements and
10 //  update an environment accordingly.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Analysis/FlowSensitive/Transfer.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/Stmt.h"
19 #include "clang/AST/StmtVisitor.h"
20 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
21 #include "llvm/Support/Casting.h"
22 #include <cassert>
23 
24 namespace clang {
25 namespace dataflow {
26 
27 class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
28 public:
29   TransferVisitor(Environment &Env) : Env(Env) {}
30 
31   void VisitDeclStmt(const DeclStmt *S) {
32     // FIXME: Add support for group decls, e.g: `int a, b;`
33     if (S->isSingleDecl()) {
34       if (const auto *D = dyn_cast<VarDecl>(S->getSingleDecl())) {
35         visitVarDecl(*D);
36       }
37     }
38   }
39 
40   // FIXME: Add support for:
41   // - BinaryOperator
42   // - CallExpr
43   // - CXXBindTemporaryExpr
44   // - CXXBoolLiteralExpr
45   // - CXXConstructExpr
46   // - CXXFunctionalCastExpr
47   // - CXXOperatorCallExpr
48   // - CXXStaticCastExpr
49   // - CXXThisExpr
50   // - DeclRefExpr
51   // - ImplicitCastExpr
52   // - MaterializeTemporaryExpr
53   // - MemberExpr
54   // - UnaryOperator
55 
56 private:
57   void visitVarDecl(const VarDecl &D) {
58     auto &Loc = Env.createStorageLocation(D);
59     Env.setStorageLocation(D, Loc);
60     Env.initValueInStorageLocation(Loc, D.getType());
61   }
62 
63   Environment &Env;
64 };
65 
66 void transfer(const Stmt &S, Environment &Env) {
67   assert(!isa<ParenExpr>(&S));
68   TransferVisitor(Env).Visit(&S);
69 }
70 
71 } // namespace dataflow
72 } // namespace clang
73