clang  7.0.0svn
ConstructionContext.h
Go to the documentation of this file.
1 //===- ConstructionContext.h - CFG constructor information ------*- C++ -*-===//
2 //
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 //
10 // This file defines the ConstructionContext class and its sub-classes,
11 // which represent various different ways of constructing C++ objects
12 // with the additional information the users may want to know about
13 // the constructor.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
18 #define LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
19 
21 #include "clang/AST/ExprCXX.h"
22 
23 namespace clang {
24 
25 /// Construction context is a linked list of multiple layers. Layers are
26 /// created gradually while traversing the AST, and layers that represent
27 /// the outmost AST nodes are built first, while the node that immediately
28 /// contains the constructor would be built last and capture the previous
29 /// layers as its parents. Construction context captures the last layer
30 /// (which has links to the previous layers) and classifies the seemingly
31 /// arbitrary chain of layers into one of the possible ways of constructing
32 /// an object in C++ for user-friendly experience.
34 public:
35  typedef llvm::PointerUnion<Stmt *, CXXCtorInitializer *> TriggerTy;
36 
37 private:
38  /// The construction site - the statement that triggered the construction
39  /// for one of its parts. For instance, stack variable declaration statement
40  /// triggers construction of itself or its elements if it's an array,
41  /// new-expression triggers construction of the newly allocated object(s).
42  TriggerTy Trigger;
43 
44  /// Sometimes a single trigger is not enough to describe the construction
45  /// site. In this case we'd have a chain of "partial" construction context
46  /// layers.
47  /// Some examples:
48  /// - A constructor within in an aggregate initializer list within a variable
49  /// would have a construction context of the initializer list with
50  /// the parent construction context of a variable.
51  /// - A constructor for a temporary that needs to be both destroyed
52  /// and materialized into an elidable copy constructor would have a
53  /// construction context of a CXXBindTemporaryExpr with the parent
54  /// construction context of a MaterializeTemproraryExpr.
55  /// Not all of these are currently supported.
56  const ConstructionContextLayer *Parent = nullptr;
57 
58  ConstructionContextLayer(TriggerTy Trigger,
59  const ConstructionContextLayer *Parent)
60  : Trigger(Trigger), Parent(Parent) {}
61 
62 public:
63  static const ConstructionContextLayer *
64  create(BumpVectorContext &C, TriggerTy Trigger,
65  const ConstructionContextLayer *Parent = nullptr);
66 
67  const ConstructionContextLayer *getParent() const { return Parent; }
68  bool isLast() const { return !Parent; }
69 
70  const Stmt *getTriggerStmt() const {
71  return Trigger.dyn_cast<Stmt *>();
72  }
73 
75  return Trigger.dyn_cast<CXXCtorInitializer *>();
76  }
77 
78  /// Returns true if these layers are equal as individual layers, even if
79  /// their parents are different.
80  bool isSameLayer(const ConstructionContextLayer *Other) const {
81  assert(Other);
82  return (Trigger == Other->Trigger);
83  }
84 
85  /// See if Other is a proper initial segment of this construction context
86  /// in terms of the parent chain - i.e. a few first parents coincide and
87  /// then the other context terminates but our context goes further - i.e.,
88  /// we are providing the same context that the other context provides,
89  /// and a bit more above that.
91 };
92 
93 
94 /// ConstructionContext's subclasses describe different ways of constructing
95 /// an object in C++. The context re-captures the essential parent AST nodes
96 /// of the CXXConstructExpr it is assigned to and presents these nodes
97 /// through easy-to-understand accessor methods.
99 public:
100  enum Kind {
103  VARIABLE_BEGIN = SimpleVariableKind,
104  VARIABLE_END = CXX17ElidedCopyVariableKind,
107  INITIALIZER_BEGIN = SimpleConstructorInitializerKind,
108  INITIALIZER_END = CXX17ElidedCopyConstructorInitializerKind,
113  RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
114  RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind
115  };
116 
117 protected:
119 
120  // Do not make public! These need to only be constructed
121  // via createFromLayers().
122  explicit ConstructionContext(Kind K) : K(K) {}
123 
124 private:
125  // A helper function for constructing an instance into a bump vector context.
126  template <typename T, typename... ArgTypes>
127  static T *create(BumpVectorContext &C, ArgTypes... Args) {
128  auto *CC = C.getAllocator().Allocate<T>();
129  return new (CC) T(Args...);
130  }
131 
132 public:
133  /// Consume the construction context layer, together with its parent layers,
134  /// and wrap it up into a complete construction context. May return null
135  /// if layers do not form any supported construction context.
136  static const ConstructionContext *
137  createFromLayers(BumpVectorContext &C,
138  const ConstructionContextLayer *TopLayer);
139 
140  Kind getKind() const { return K; }
141 };
142 
143 /// An abstract base class for local variable constructors.
145  const DeclStmt *DS;
146 
147 protected:
149  : ConstructionContext(K), DS(DS) {
150  assert(classof(this));
151  assert(DS);
152  }
153 
154 public:
155  const DeclStmt *getDeclStmt() const { return DS; }
156 
157  static bool classof(const ConstructionContext *CC) {
158  return CC->getKind() >= VARIABLE_BEGIN &&
159  CC->getKind() <= VARIABLE_END;
160  }
161 };
162 
163 /// Represents construction into a simple local variable, eg. T var(123);.
164 /// If a variable has an initializer, eg. T var = makeT();, then the final
165 /// elidable copy-constructor from makeT() into var would also be a simple
166 /// variable constructor handled by this class.
168  friend class ConstructionContext; // Allows to create<>() itself.
169 
170  explicit SimpleVariableConstructionContext(const DeclStmt *DS)
171  : VariableConstructionContext(ConstructionContext::SimpleVariableKind,
172  DS) {}
173 
174 public:
175  static bool classof(const ConstructionContext *CC) {
176  return CC->getKind() == SimpleVariableKind;
177  }
178 };
179 
180 /// Represents construction into a simple variable with an initializer syntax,
181 /// with a single constructor, eg. T var = makeT();. Such construction context
182 /// may only appear in C++17 because previously it was split into a temporary
183 /// object constructor and an elidable simple variable copy-constructor and
184 /// we were producing separate construction contexts for these constructors.
185 /// In C++17 we have a single construction context that combines both.
186 /// Note that if the object has trivial destructor, then this code is
187 /// indistinguishable from a simple variable constructor on the AST level;
188 /// in this case we provide a simple variable construction context.
190  : public VariableConstructionContext {
191  const CXXBindTemporaryExpr *BTE;
192 
193  friend class ConstructionContext; // Allows to create<>() itself.
194 
196  const DeclStmt *DS, const CXXBindTemporaryExpr *BTE)
197  : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) {
198  assert(BTE);
199  }
200 
201 public:
202  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
203 
204  static bool classof(const ConstructionContext *CC) {
205  return CC->getKind() == CXX17ElidedCopyVariableKind;
206  }
207 };
208 
209 // An abstract base class for constructor-initializer-based constructors.
211  const CXXCtorInitializer *I;
212 
213 protected:
216  : ConstructionContext(K), I(I) {
217  assert(classof(this));
218  assert(I);
219  }
220 
221 public:
222  const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }
223 
224  static bool classof(const ConstructionContext *CC) {
225  return CC->getKind() >= INITIALIZER_BEGIN &&
226  CC->getKind() <= INITIALIZER_END;
227  }
228 };
229 
230 /// Represents construction into a field or a base class within a bigger object
231 /// via a constructor initializer, eg. T(): field(123) { ... }.
234  friend class ConstructionContext; // Allows to create<>() itself.
235 
237  const CXXCtorInitializer *I)
239  ConstructionContext::SimpleConstructorInitializerKind, I) {}
240 
241 public:
242  static bool classof(const ConstructionContext *CC) {
243  return CC->getKind() == SimpleConstructorInitializerKind;
244  }
245 };
246 
247 /// Represents construction into a field or a base class within a bigger object
248 /// via a constructor initializer, with a single constructor, eg.
249 /// T(): field(Field(123)) { ... }. Such construction context may only appear
250 /// in C++17 because previously it was split into a temporary object constructor
251 /// and an elidable simple constructor-initializer copy-constructor and we were
252 /// producing separate construction contexts for these constructors. In C++17
253 /// we have a single construction context that combines both. Note that if the
254 /// object has trivial destructor, then this code is indistinguishable from
255 /// a simple constructor-initializer constructor on the AST level; in this case
256 /// we provide a simple constructor-initializer construction context.
259  const CXXBindTemporaryExpr *BTE;
260 
261  friend class ConstructionContext; // Allows to create<>() itself.
262 
264  const CXXCtorInitializer *I, const CXXBindTemporaryExpr *BTE)
266  CXX17ElidedCopyConstructorInitializerKind, I),
267  BTE(BTE) {
268  assert(BTE);
269  }
270 
271 public:
272  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
273 
274  static bool classof(const ConstructionContext *CC) {
275  return CC->getKind() == CXX17ElidedCopyConstructorInitializerKind;
276  }
277 };
278 
279 /// Represents immediate initialization of memory allocated by operator new,
280 /// eg. new T(123);.
282  const CXXNewExpr *NE;
283 
284  friend class ConstructionContext; // Allows to create<>() itself.
285 
287  : ConstructionContext(ConstructionContext::NewAllocatedObjectKind),
288  NE(NE) {
289  assert(NE);
290  }
291 
292 public:
293  const CXXNewExpr *getCXXNewExpr() const { return NE; }
294 
295  static bool classof(const ConstructionContext *CC) {
296  return CC->getKind() == NewAllocatedObjectKind;
297  }
298 };
299 
300 /// Represents a temporary object, eg. T(123), that does not immediately cross
301 /// function boundaries "by value"; constructors that construct function
302 /// value-type arguments or values that are immediately returned from the
303 /// function that returns a value receive separate construction context kinds.
305  const CXXBindTemporaryExpr *BTE;
306  const MaterializeTemporaryExpr *MTE;
307 
308  friend class ConstructionContext; // Allows to create<>() itself.
309 
311  const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)
312  : ConstructionContext(ConstructionContext::TemporaryObjectKind),
313  BTE(BTE), MTE(MTE) {
314  // Both BTE and MTE can be null here, all combinations possible.
315  // Even though for now at least one should be non-null, we simply haven't
316  // implemented this case yet (this would be a temporary in the middle of
317  // nowhere that doesn't have a non-trivial destructor).
318  }
319 
320 public:
321  /// CXXBindTemporaryExpr here is non-null as long as the temporary has
322  /// a non-trivial destructor.
324  return BTE;
325  }
326 
327  /// MaterializeTemporaryExpr is non-null as long as the temporary is actually
328  /// used after construction, eg. by binding to a reference (lifetime
329  /// extension), accessing a field, calling a method, or passing it into
330  /// a function (an elidable copy or move constructor would be a common
331  /// example) by reference.
333  return MTE;
334  }
335 
336  static bool classof(const ConstructionContext *CC) {
337  return CC->getKind() == TemporaryObjectKind;
338  }
339 };
340 
342  const ReturnStmt *RS;
343 
344 protected:
346  const ReturnStmt *RS)
347  : ConstructionContext(K), RS(RS) {
348  assert(classof(this));
349  assert(RS);
350  }
351 
352 public:
353  const ReturnStmt *getReturnStmt() const { return RS; }
354 
355  static bool classof(const ConstructionContext *CC) {
356  return CC->getKind() >= RETURNED_VALUE_BEGIN &&
357  CC->getKind() <= RETURNED_VALUE_END;
358  }
359 };
360 
361 /// Represents a temporary object that is being immediately returned from a
362 /// function by value, eg. return t; or return T(123);. In this case there is
363 /// always going to be a constructor at the return site. However, the usual
364 /// temporary-related bureaucracy (CXXBindTemporaryExpr,
365 /// MaterializeTemporaryExpr) is normally located in the caller function's AST.
368  friend class ConstructionContext; // Allows to create<>() itself.
369 
372  ConstructionContext::SimpleReturnedValueKind, RS) {}
373 
374 public:
375  static bool classof(const ConstructionContext *CC) {
376  return CC->getKind() == SimpleReturnedValueKind;
377  }
378 };
379 
380 /// Represents a temporary object that is being immediately returned from a
381 /// function by value, eg. return t; or return T(123); in C++17.
382 /// In C++17 there is not going to be an elidable copy constructor at the
383 /// return site. However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr,
384 /// MaterializeTemporaryExpr) is normally located in the caller function's AST.
385 /// Note that if the object has trivial destructor, then this code is
386 /// indistinguishable from a simple returned value constructor on the AST level;
387 /// in this case we provide a simple returned value construction context.
390  const CXXBindTemporaryExpr *BTE;
391 
392  friend class ConstructionContext; // Allows to create<>() itself.
393 
395  const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE)
397  ConstructionContext::CXX17ElidedCopyReturnedValueKind, RS),
398  BTE(BTE) {
399  assert(BTE);
400  }
401 
402 public:
403  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
404 
405  static bool classof(const ConstructionContext *CC) {
406  return CC->getKind() == CXX17ElidedCopyReturnedValueKind;
407  }
408 };
409 
410 } // end namespace clang
411 
412 #endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
static bool classof(const ConstructionContext *CC)
const DeclStmt * getDeclStmt() const
Stmt - This represents one statement.
Definition: Stmt.h:66
VariableConstructionContext(ConstructionContext::Kind K, const DeclStmt *DS)
bool isSameLayer(const ConstructionContextLayer *Other) const
Returns true if these layers are equal as individual layers, even if their parents are different...
bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const
See if Other is a proper initial segment of this construction context in terms of the parent chain - ...
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
Definition: ExprCXX.h:4039
llvm::BumpPtrAllocator & getAllocator()
Definition: BumpVector.h:56
const CXXCtorInitializer * getTriggerInit() const
Defines the clang::Expr interface and subclasses for C++ expressions.
ReturnedValueConstructionContext(ConstructionContext::Kind K, const ReturnStmt *RS)
Represents construction into a field or a base class within a bigger object via a constructor initial...
static bool classof(const ConstructionContext *CC)
const ConstructionContextLayer * getParent() const
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1196
An abstract base class for local variable constructors.
static bool classof(const ConstructionContext *CC)
const MaterializeTemporaryExpr * getMaterializedTemporaryExpr() const
MaterializeTemporaryExpr is non-null as long as the temporary is actually used after construction...
static bool classof(const ConstructionContext *CC)
const FunctionProtoType * T
static bool classof(const ConstructionContext *CC)
Represents a temporary object that is being immediately returned from a function by value...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
Definition: Stmt.h:1433
const CXXBindTemporaryExpr * getCXXBindTemporaryExpr() const
CXXBindTemporaryExpr here is non-null as long as the temporary has a non-trivial destructor.
ConstructorInitializerConstructionContext(ConstructionContext::Kind K, const CXXCtorInitializer *I)
const CXXCtorInitializer * getCXXCtorInitializer() const
Construction context is a linked list of multiple layers.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Definition: ExprCXX.h:1845
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:499
const CXXBindTemporaryExpr * getCXXBindTemporaryExpr() const
static bool classof(const ConstructionContext *CC)
const CXXBindTemporaryExpr * getCXXBindTemporaryExpr() const
Dataflow Directional Tag Classes.
Represents immediate initialization of memory allocated by operator new, eg.
Represents a temporary object that is being immediately returned from a function by value...
static bool classof(const OMPClause *T)
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2238
Represents a temporary object, eg.
static const ConstructionContextLayer * create(BumpVectorContext &C, TriggerTy Trigger, const ConstructionContextLayer *Parent=nullptr)
static bool classof(const ConstructionContext *CC)
ConstructionContext&#39;s subclasses describe different ways of constructing an object in C++...
Represents construction into a field or a base class within a bigger object via a constructor initial...
Represents construction into a simple local variable, eg.
static bool classof(const ConstructionContext *CC)
Represents construction into a simple variable with an initializer syntax, with a single constructor...
static bool classof(const ConstructionContext *CC)
static bool classof(const ConstructionContext *CC)
llvm::PointerUnion< Stmt *, CXXCtorInitializer * > TriggerTy