ConstructionContext.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- ConstructionContext.h - CFG constructor information ------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the ConstructionContext class and its sub-classes,
  15. // which represent various different ways of constructing C++ objects
  16. // with the additional information the users may want to know about
  17. // the constructor.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
  21. #define LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
  22. #include "clang/Analysis/Support/BumpVector.h"
  23. #include "clang/AST/ExprCXX.h"
  24. #include "clang/AST/ExprObjC.h"
  25. namespace clang {
  26. /// Represents a single point (AST node) in the program that requires attention
  27. /// during construction of an object. ConstructionContext would be represented
  28. /// as a list of such items.
  29. class ConstructionContextItem {
  30. public:
  31. enum ItemKind {
  32. VariableKind,
  33. NewAllocatorKind,
  34. ReturnKind,
  35. MaterializationKind,
  36. TemporaryDestructorKind,
  37. ElidedDestructorKind,
  38. ElidableConstructorKind,
  39. ArgumentKind,
  40. STATEMENT_WITH_INDEX_KIND_BEGIN=ArgumentKind,
  41. STATEMENT_WITH_INDEX_KIND_END=ArgumentKind,
  42. STATEMENT_KIND_BEGIN = VariableKind,
  43. STATEMENT_KIND_END = ArgumentKind,
  44. InitializerKind,
  45. INITIALIZER_KIND_BEGIN=InitializerKind,
  46. INITIALIZER_KIND_END=InitializerKind
  47. };
  48. LLVM_DUMP_METHOD static StringRef getKindAsString(ItemKind K) {
  49. switch (K) {
  50. case VariableKind: return "construct into local variable";
  51. case NewAllocatorKind: return "construct into new-allocator";
  52. case ReturnKind: return "construct into return address";
  53. case MaterializationKind: return "materialize temporary";
  54. case TemporaryDestructorKind: return "destroy temporary";
  55. case ElidedDestructorKind: return "elide destructor";
  56. case ElidableConstructorKind: return "elide constructor";
  57. case ArgumentKind: return "construct into argument";
  58. case InitializerKind: return "construct into member variable";
  59. };
  60. llvm_unreachable("Unknown ItemKind");
  61. }
  62. private:
  63. const void *const Data;
  64. const ItemKind Kind;
  65. const unsigned Index = 0;
  66. bool hasStatement() const {
  67. return Kind >= STATEMENT_KIND_BEGIN &&
  68. Kind <= STATEMENT_KIND_END;
  69. }
  70. bool hasIndex() const {
  71. return Kind >= STATEMENT_WITH_INDEX_KIND_BEGIN &&
  72. Kind >= STATEMENT_WITH_INDEX_KIND_END;
  73. }
  74. bool hasInitializer() const {
  75. return Kind >= INITIALIZER_KIND_BEGIN &&
  76. Kind <= INITIALIZER_KIND_END;
  77. }
  78. public:
  79. // ConstructionContextItem should be simple enough so that it was easy to
  80. // re-construct it from the AST node it captures. For that reason we provide
  81. // simple implicit conversions from all sorts of supported AST nodes.
  82. ConstructionContextItem(const DeclStmt *DS)
  83. : Data(DS), Kind(VariableKind) {}
  84. ConstructionContextItem(const CXXNewExpr *NE)
  85. : Data(NE), Kind(NewAllocatorKind) {}
  86. ConstructionContextItem(const ReturnStmt *RS)
  87. : Data(RS), Kind(ReturnKind) {}
  88. ConstructionContextItem(const MaterializeTemporaryExpr *MTE)
  89. : Data(MTE), Kind(MaterializationKind) {}
  90. ConstructionContextItem(const CXXBindTemporaryExpr *BTE,
  91. bool IsElided = false)
  92. : Data(BTE),
  93. Kind(IsElided ? ElidedDestructorKind : TemporaryDestructorKind) {}
  94. ConstructionContextItem(const CXXConstructExpr *CE)
  95. : Data(CE), Kind(ElidableConstructorKind) {}
  96. ConstructionContextItem(const CallExpr *CE, unsigned Index)
  97. : Data(CE), Kind(ArgumentKind), Index(Index) {}
  98. ConstructionContextItem(const CXXConstructExpr *CE, unsigned Index)
  99. : Data(CE), Kind(ArgumentKind), Index(Index) {}
  100. ConstructionContextItem(const CXXInheritedCtorInitExpr *CE, unsigned Index)
  101. : Data(CE), Kind(ArgumentKind), Index(Index) {}
  102. ConstructionContextItem(const ObjCMessageExpr *ME, unsigned Index)
  103. : Data(ME), Kind(ArgumentKind), Index(Index) {}
  104. // A polymorphic version of the previous calls with dynamic type check.
  105. ConstructionContextItem(const Expr *E, unsigned Index)
  106. : Data(E), Kind(ArgumentKind), Index(Index) {
  107. assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
  108. isa<CXXInheritedCtorInitExpr>(E) || isa<ObjCMessageExpr>(E));
  109. }
  110. ConstructionContextItem(const CXXCtorInitializer *Init)
  111. : Data(Init), Kind(InitializerKind), Index(0) {}
  112. ItemKind getKind() const { return Kind; }
  113. LLVM_DUMP_METHOD StringRef getKindAsString() const {
  114. return getKindAsString(getKind());
  115. }
  116. /// The construction site - the statement that triggered the construction
  117. /// for one of its parts. For instance, stack variable declaration statement
  118. /// triggers construction of itself or its elements if it's an array,
  119. /// new-expression triggers construction of the newly allocated object(s).
  120. const Stmt *getStmt() const {
  121. assert(hasStatement());
  122. return static_cast<const Stmt *>(Data);
  123. }
  124. const Stmt *getStmtOrNull() const {
  125. return hasStatement() ? getStmt() : nullptr;
  126. }
  127. /// The construction site is not necessarily a statement. It may also be a
  128. /// CXXCtorInitializer, which means that a member variable is being
  129. /// constructed during initialization of the object that contains it.
  130. const CXXCtorInitializer *getCXXCtorInitializer() const {
  131. assert(hasInitializer());
  132. return static_cast<const CXXCtorInitializer *>(Data);
  133. }
  134. /// If a single trigger statement triggers multiple constructors, they are
  135. /// usually being enumerated. This covers function argument constructors
  136. /// triggered by a call-expression and items in an initializer list triggered
  137. /// by an init-list-expression.
  138. unsigned getIndex() const {
  139. // This is a fairly specific request. Let's make sure the user knows
  140. // what he's doing.
  141. assert(hasIndex());
  142. return Index;
  143. }
  144. void Profile(llvm::FoldingSetNodeID &ID) const {
  145. ID.AddPointer(Data);
  146. ID.AddInteger(Kind);
  147. ID.AddInteger(Index);
  148. }
  149. bool operator==(const ConstructionContextItem &Other) const {
  150. // For most kinds the Index comparison is trivially true, but
  151. // checking kind separately doesn't seem to be less expensive
  152. // than checking Index. Same in operator<().
  153. return std::make_tuple(Data, Kind, Index) ==
  154. std::make_tuple(Other.Data, Other.Kind, Other.Index);
  155. }
  156. bool operator<(const ConstructionContextItem &Other) const {
  157. return std::make_tuple(Data, Kind, Index) <
  158. std::make_tuple(Other.Data, Other.Kind, Other.Index);
  159. }
  160. };
  161. /// Construction context can be seen as a linked list of multiple layers.
  162. /// Sometimes a single trigger is not enough to describe the construction
  163. /// site. That's what causing us to have a chain of "partial" construction
  164. /// context layers. Some examples:
  165. /// - A constructor within in an aggregate initializer list within a variable
  166. /// would have a construction context of the initializer list with
  167. /// the parent construction context of a variable.
  168. /// - A constructor for a temporary that needs to be both destroyed
  169. /// and materialized into an elidable copy constructor would have a
  170. /// construction context of a CXXBindTemporaryExpr with the parent
  171. /// construction context of a MaterializeTemproraryExpr.
  172. /// Not all of these are currently supported.
  173. /// Layers are created gradually while traversing the AST, and layers that
  174. /// represent the outmost AST nodes are built first, while the node that
  175. /// immediately contains the constructor would be built last and capture the
  176. /// previous layers as its parents. Construction context captures the last layer
  177. /// (which has links to the previous layers) and classifies the seemingly
  178. /// arbitrary chain of layers into one of the possible ways of constructing
  179. /// an object in C++ for user-friendly experience.
  180. class ConstructionContextLayer {
  181. const ConstructionContextLayer *Parent = nullptr;
  182. ConstructionContextItem Item;
  183. ConstructionContextLayer(ConstructionContextItem Item,
  184. const ConstructionContextLayer *Parent)
  185. : Parent(Parent), Item(Item) {}
  186. public:
  187. static const ConstructionContextLayer *
  188. create(BumpVectorContext &C, const ConstructionContextItem &Item,
  189. const ConstructionContextLayer *Parent = nullptr);
  190. const ConstructionContextItem &getItem() const { return Item; }
  191. const ConstructionContextLayer *getParent() const { return Parent; }
  192. bool isLast() const { return !Parent; }
  193. /// See if Other is a proper initial segment of this construction context
  194. /// in terms of the parent chain - i.e. a few first parents coincide and
  195. /// then the other context terminates but our context goes further - i.e.,
  196. /// we are providing the same context that the other context provides,
  197. /// and a bit more above that.
  198. bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const;
  199. };
  200. /// ConstructionContext's subclasses describe different ways of constructing
  201. /// an object in C++. The context re-captures the essential parent AST nodes
  202. /// of the CXXConstructExpr it is assigned to and presents these nodes
  203. /// through easy-to-understand accessor methods.
  204. class ConstructionContext {
  205. public:
  206. enum Kind {
  207. SimpleVariableKind,
  208. CXX17ElidedCopyVariableKind,
  209. VARIABLE_BEGIN = SimpleVariableKind,
  210. VARIABLE_END = CXX17ElidedCopyVariableKind,
  211. SimpleConstructorInitializerKind,
  212. CXX17ElidedCopyConstructorInitializerKind,
  213. INITIALIZER_BEGIN = SimpleConstructorInitializerKind,
  214. INITIALIZER_END = CXX17ElidedCopyConstructorInitializerKind,
  215. NewAllocatedObjectKind,
  216. SimpleTemporaryObjectKind,
  217. ElidedTemporaryObjectKind,
  218. TEMPORARY_BEGIN = SimpleTemporaryObjectKind,
  219. TEMPORARY_END = ElidedTemporaryObjectKind,
  220. SimpleReturnedValueKind,
  221. CXX17ElidedCopyReturnedValueKind,
  222. RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
  223. RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind,
  224. ArgumentKind
  225. };
  226. protected:
  227. Kind K;
  228. // Do not make public! These need to only be constructed
  229. // via createFromLayers().
  230. explicit ConstructionContext(Kind K) : K(K) {}
  231. private:
  232. // A helper function for constructing an instance into a bump vector context.
  233. template <typename T, typename... ArgTypes>
  234. static T *create(BumpVectorContext &C, ArgTypes... Args) {
  235. auto *CC = C.getAllocator().Allocate<T>();
  236. return new (CC) T(Args...);
  237. }
  238. // A sub-routine of createFromLayers() that deals with temporary objects
  239. // that need to be materialized. The BTE argument is for the situation when
  240. // the object also needs to be bound for destruction.
  241. static const ConstructionContext *createMaterializedTemporaryFromLayers(
  242. BumpVectorContext &C, const MaterializeTemporaryExpr *MTE,
  243. const CXXBindTemporaryExpr *BTE,
  244. const ConstructionContextLayer *ParentLayer);
  245. // A sub-routine of createFromLayers() that deals with temporary objects
  246. // that need to be bound for destruction. Automatically finds out if the
  247. // object also needs to be materialized and delegates to
  248. // createMaterializedTemporaryFromLayers() if necessary.
  249. static const ConstructionContext *
  250. createBoundTemporaryFromLayers(
  251. BumpVectorContext &C, const CXXBindTemporaryExpr *BTE,
  252. const ConstructionContextLayer *ParentLayer);
  253. public:
  254. /// Consume the construction context layer, together with its parent layers,
  255. /// and wrap it up into a complete construction context. May return null
  256. /// if layers do not form any supported construction context.
  257. static const ConstructionContext *
  258. createFromLayers(BumpVectorContext &C,
  259. const ConstructionContextLayer *TopLayer);
  260. Kind getKind() const { return K; }
  261. };
  262. /// An abstract base class for local variable constructors.
  263. class VariableConstructionContext : public ConstructionContext {
  264. const DeclStmt *DS;
  265. protected:
  266. VariableConstructionContext(ConstructionContext::Kind K, const DeclStmt *DS)
  267. : ConstructionContext(K), DS(DS) {
  268. assert(classof(this));
  269. assert(DS);
  270. }
  271. public:
  272. const DeclStmt *getDeclStmt() const { return DS; }
  273. static bool classof(const ConstructionContext *CC) {
  274. return CC->getKind() >= VARIABLE_BEGIN &&
  275. CC->getKind() <= VARIABLE_END;
  276. }
  277. };
  278. /// Represents construction into a simple local variable, eg. T var(123);.
  279. /// If a variable has an initializer, eg. T var = makeT();, then the final
  280. /// elidable copy-constructor from makeT() into var would also be a simple
  281. /// variable constructor handled by this class.
  282. class SimpleVariableConstructionContext : public VariableConstructionContext {
  283. friend class ConstructionContext; // Allows to create<>() itself.
  284. explicit SimpleVariableConstructionContext(const DeclStmt *DS)
  285. : VariableConstructionContext(ConstructionContext::SimpleVariableKind,
  286. DS) {}
  287. public:
  288. static bool classof(const ConstructionContext *CC) {
  289. return CC->getKind() == SimpleVariableKind;
  290. }
  291. };
  292. /// Represents construction into a simple variable with an initializer syntax,
  293. /// with a single constructor, eg. T var = makeT();. Such construction context
  294. /// may only appear in C++17 because previously it was split into a temporary
  295. /// object constructor and an elidable simple variable copy-constructor and
  296. /// we were producing separate construction contexts for these constructors.
  297. /// In C++17 we have a single construction context that combines both.
  298. /// Note that if the object has trivial destructor, then this code is
  299. /// indistinguishable from a simple variable constructor on the AST level;
  300. /// in this case we provide a simple variable construction context.
  301. class CXX17ElidedCopyVariableConstructionContext
  302. : public VariableConstructionContext {
  303. const CXXBindTemporaryExpr *BTE;
  304. friend class ConstructionContext; // Allows to create<>() itself.
  305. explicit CXX17ElidedCopyVariableConstructionContext(
  306. const DeclStmt *DS, const CXXBindTemporaryExpr *BTE)
  307. : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) {
  308. assert(BTE);
  309. }
  310. public:
  311. const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
  312. static bool classof(const ConstructionContext *CC) {
  313. return CC->getKind() == CXX17ElidedCopyVariableKind;
  314. }
  315. };
  316. // An abstract base class for constructor-initializer-based constructors.
  317. class ConstructorInitializerConstructionContext : public ConstructionContext {
  318. const CXXCtorInitializer *I;
  319. protected:
  320. explicit ConstructorInitializerConstructionContext(
  321. ConstructionContext::Kind K, const CXXCtorInitializer *I)
  322. : ConstructionContext(K), I(I) {
  323. assert(classof(this));
  324. assert(I);
  325. }
  326. public:
  327. const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }
  328. static bool classof(const ConstructionContext *CC) {
  329. return CC->getKind() >= INITIALIZER_BEGIN &&
  330. CC->getKind() <= INITIALIZER_END;
  331. }
  332. };
  333. /// Represents construction into a field or a base class within a bigger object
  334. /// via a constructor initializer, eg. T(): field(123) { ... }.
  335. class SimpleConstructorInitializerConstructionContext
  336. : public ConstructorInitializerConstructionContext {
  337. friend class ConstructionContext; // Allows to create<>() itself.
  338. explicit SimpleConstructorInitializerConstructionContext(
  339. const CXXCtorInitializer *I)
  340. : ConstructorInitializerConstructionContext(
  341. ConstructionContext::SimpleConstructorInitializerKind, I) {}
  342. public:
  343. static bool classof(const ConstructionContext *CC) {
  344. return CC->getKind() == SimpleConstructorInitializerKind;
  345. }
  346. };
  347. /// Represents construction into a field or a base class within a bigger object
  348. /// via a constructor initializer, with a single constructor, eg.
  349. /// T(): field(Field(123)) { ... }. Such construction context may only appear
  350. /// in C++17 because previously it was split into a temporary object constructor
  351. /// and an elidable simple constructor-initializer copy-constructor and we were
  352. /// producing separate construction contexts for these constructors. In C++17
  353. /// we have a single construction context that combines both. Note that if the
  354. /// object has trivial destructor, then this code is indistinguishable from
  355. /// a simple constructor-initializer constructor on the AST level; in this case
  356. /// we provide a simple constructor-initializer construction context.
  357. class CXX17ElidedCopyConstructorInitializerConstructionContext
  358. : public ConstructorInitializerConstructionContext {
  359. const CXXBindTemporaryExpr *BTE;
  360. friend class ConstructionContext; // Allows to create<>() itself.
  361. explicit CXX17ElidedCopyConstructorInitializerConstructionContext(
  362. const CXXCtorInitializer *I, const CXXBindTemporaryExpr *BTE)
  363. : ConstructorInitializerConstructionContext(
  364. CXX17ElidedCopyConstructorInitializerKind, I),
  365. BTE(BTE) {
  366. assert(BTE);
  367. }
  368. public:
  369. const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
  370. static bool classof(const ConstructionContext *CC) {
  371. return CC->getKind() == CXX17ElidedCopyConstructorInitializerKind;
  372. }
  373. };
  374. /// Represents immediate initialization of memory allocated by operator new,
  375. /// eg. new T(123);.
  376. class NewAllocatedObjectConstructionContext : public ConstructionContext {
  377. const CXXNewExpr *NE;
  378. friend class ConstructionContext; // Allows to create<>() itself.
  379. explicit NewAllocatedObjectConstructionContext(const CXXNewExpr *NE)
  380. : ConstructionContext(ConstructionContext::NewAllocatedObjectKind),
  381. NE(NE) {
  382. assert(NE);
  383. }
  384. public:
  385. const CXXNewExpr *getCXXNewExpr() const { return NE; }
  386. static bool classof(const ConstructionContext *CC) {
  387. return CC->getKind() == NewAllocatedObjectKind;
  388. }
  389. };
  390. /// Represents a temporary object, eg. T(123), that does not immediately cross
  391. /// function boundaries "by value"; constructors that construct function
  392. /// value-type arguments or values that are immediately returned from the
  393. /// function that returns a value receive separate construction context kinds.
  394. class TemporaryObjectConstructionContext : public ConstructionContext {
  395. const CXXBindTemporaryExpr *BTE;
  396. const MaterializeTemporaryExpr *MTE;
  397. protected:
  398. explicit TemporaryObjectConstructionContext(
  399. ConstructionContext::Kind K, const CXXBindTemporaryExpr *BTE,
  400. const MaterializeTemporaryExpr *MTE)
  401. : ConstructionContext(K), BTE(BTE), MTE(MTE) {
  402. // Both BTE and MTE can be null here, all combinations possible.
  403. // Even though for now at least one should be non-null, we simply haven't
  404. // implemented the other case yet (this would be a temporary in the middle
  405. // of nowhere that doesn't have a non-trivial destructor).
  406. }
  407. public:
  408. /// CXXBindTemporaryExpr here is non-null as long as the temporary has
  409. /// a non-trivial destructor.
  410. const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const {
  411. return BTE;
  412. }
  413. /// MaterializeTemporaryExpr is non-null as long as the temporary is actually
  414. /// used after construction, eg. by binding to a reference (lifetime
  415. /// extension), accessing a field, calling a method, or passing it into
  416. /// a function (an elidable copy or move constructor would be a common
  417. /// example) by reference.
  418. const MaterializeTemporaryExpr *getMaterializedTemporaryExpr() const {
  419. return MTE;
  420. }
  421. static bool classof(const ConstructionContext *CC) {
  422. return CC->getKind() >= TEMPORARY_BEGIN && CC->getKind() <= TEMPORARY_END;
  423. }
  424. };
  425. /// Represents a temporary object that is not constructed for the purpose of
  426. /// being immediately copied/moved by an elidable copy/move-constructor.
  427. /// This includes temporary objects "in the middle of nowhere" like T(123) and
  428. /// lifetime-extended temporaries.
  429. class SimpleTemporaryObjectConstructionContext
  430. : public TemporaryObjectConstructionContext {
  431. friend class ConstructionContext; // Allows to create<>() itself.
  432. explicit SimpleTemporaryObjectConstructionContext(
  433. const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)
  434. : TemporaryObjectConstructionContext(
  435. ConstructionContext::SimpleTemporaryObjectKind, BTE, MTE) {}
  436. public:
  437. static bool classof(const ConstructionContext *CC) {
  438. return CC->getKind() == SimpleTemporaryObjectKind;
  439. }
  440. };
  441. /// Represents a temporary object that is constructed for the sole purpose
  442. /// of being immediately copied by an elidable copy/move constructor.
  443. /// For example, T t = T(123); includes a temporary T(123) that is immediately
  444. /// copied to variable t. In such cases the elidable copy can (but not
  445. /// necessarily should) be omitted ("elided") accodring to the rules of the
  446. /// language; the constructor would then construct variable t directly.
  447. /// This construction context contains information of the elidable constructor
  448. /// and its respective construction context.
  449. class ElidedTemporaryObjectConstructionContext
  450. : public TemporaryObjectConstructionContext {
  451. const CXXConstructExpr *ElidedCE;
  452. const ConstructionContext *ElidedCC;
  453. friend class ConstructionContext; // Allows to create<>() itself.
  454. explicit ElidedTemporaryObjectConstructionContext(
  455. const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE,
  456. const CXXConstructExpr *ElidedCE, const ConstructionContext *ElidedCC)
  457. : TemporaryObjectConstructionContext(
  458. ConstructionContext::ElidedTemporaryObjectKind, BTE, MTE),
  459. ElidedCE(ElidedCE), ElidedCC(ElidedCC) {
  460. // Elided constructor and its context should be either both specified
  461. // or both unspecified. In the former case, the constructor must be
  462. // elidable.
  463. assert(ElidedCE && ElidedCE->isElidable() && ElidedCC);
  464. }
  465. public:
  466. const CXXConstructExpr *getConstructorAfterElision() const {
  467. return ElidedCE;
  468. }
  469. const ConstructionContext *getConstructionContextAfterElision() const {
  470. return ElidedCC;
  471. }
  472. static bool classof(const ConstructionContext *CC) {
  473. return CC->getKind() == ElidedTemporaryObjectKind;
  474. }
  475. };
  476. class ReturnedValueConstructionContext : public ConstructionContext {
  477. const ReturnStmt *RS;
  478. protected:
  479. explicit ReturnedValueConstructionContext(ConstructionContext::Kind K,
  480. const ReturnStmt *RS)
  481. : ConstructionContext(K), RS(RS) {
  482. assert(classof(this));
  483. assert(RS);
  484. }
  485. public:
  486. const ReturnStmt *getReturnStmt() const { return RS; }
  487. static bool classof(const ConstructionContext *CC) {
  488. return CC->getKind() >= RETURNED_VALUE_BEGIN &&
  489. CC->getKind() <= RETURNED_VALUE_END;
  490. }
  491. };
  492. /// Represents a temporary object that is being immediately returned from a
  493. /// function by value, eg. return t; or return T(123);. In this case there is
  494. /// always going to be a constructor at the return site. However, the usual
  495. /// temporary-related bureaucracy (CXXBindTemporaryExpr,
  496. /// MaterializeTemporaryExpr) is normally located in the caller function's AST.
  497. class SimpleReturnedValueConstructionContext
  498. : public ReturnedValueConstructionContext {
  499. friend class ConstructionContext; // Allows to create<>() itself.
  500. explicit SimpleReturnedValueConstructionContext(const ReturnStmt *RS)
  501. : ReturnedValueConstructionContext(
  502. ConstructionContext::SimpleReturnedValueKind, RS) {}
  503. public:
  504. static bool classof(const ConstructionContext *CC) {
  505. return CC->getKind() == SimpleReturnedValueKind;
  506. }
  507. };
  508. /// Represents a temporary object that is being immediately returned from a
  509. /// function by value, eg. return t; or return T(123); in C++17.
  510. /// In C++17 there is not going to be an elidable copy constructor at the
  511. /// return site. However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr,
  512. /// MaterializeTemporaryExpr) is normally located in the caller function's AST.
  513. /// Note that if the object has trivial destructor, then this code is
  514. /// indistinguishable from a simple returned value constructor on the AST level;
  515. /// in this case we provide a simple returned value construction context.
  516. class CXX17ElidedCopyReturnedValueConstructionContext
  517. : public ReturnedValueConstructionContext {
  518. const CXXBindTemporaryExpr *BTE;
  519. friend class ConstructionContext; // Allows to create<>() itself.
  520. explicit CXX17ElidedCopyReturnedValueConstructionContext(
  521. const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE)
  522. : ReturnedValueConstructionContext(
  523. ConstructionContext::CXX17ElidedCopyReturnedValueKind, RS),
  524. BTE(BTE) {
  525. assert(BTE);
  526. }
  527. public:
  528. const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
  529. static bool classof(const ConstructionContext *CC) {
  530. return CC->getKind() == CXX17ElidedCopyReturnedValueKind;
  531. }
  532. };
  533. class ArgumentConstructionContext : public ConstructionContext {
  534. // The call of which the context is an argument.
  535. const Expr *CE;
  536. // Which argument we're constructing. Note that when numbering between
  537. // arguments and parameters is inconsistent (eg., operator calls),
  538. // this is the index of the argument, not of the parameter.
  539. unsigned Index;
  540. // Whether the object needs to be destroyed.
  541. const CXXBindTemporaryExpr *BTE;
  542. friend class ConstructionContext; // Allows to create<>() itself.
  543. explicit ArgumentConstructionContext(const Expr *CE, unsigned Index,
  544. const CXXBindTemporaryExpr *BTE)
  545. : ConstructionContext(ArgumentKind), CE(CE),
  546. Index(Index), BTE(BTE) {
  547. assert(isa<CallExpr>(CE) || isa<CXXConstructExpr>(CE) ||
  548. isa<ObjCMessageExpr>(CE));
  549. // BTE is optional.
  550. }
  551. public:
  552. const Expr *getCallLikeExpr() const { return CE; }
  553. unsigned getIndex() const { return Index; }
  554. const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
  555. static bool classof(const ConstructionContext *CC) {
  556. return CC->getKind() == ArgumentKind;
  557. }
  558. };
  559. } // end namespace clang
  560. #endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
  561. #ifdef __GNUC__
  562. #pragma GCC diagnostic pop
  563. #endif