blob: 434c72c5540bf3a82fb6e6f6a2a5f9199ae85749 [file] [log] [blame]
Sebastian Redla55e52c2008-11-25 22:21:31 +00001//===--- AstGuard.h - Parser Ownership Tracking Utilities -------*- 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 RAII objects for managing ExprTy* and StmtTy*.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_PARSE_ASTGUARD_H
15#define LLVM_CLANG_PARSE_ASTGUARD_H
16
17#include "clang/Parse/Action.h"
18#include "llvm/ADT/SmallVector.h"
19
20namespace clang
21{
22 /// RAII guard for freeing StmtTys and ExprTys on early exit in the parser.
23 /// Instantiated for statements and expressions (Action::DeleteStmt and
24 /// Action::DeleteExpr).
25 template <void (Action::*Destroyer)(void*)>
26 class ASTGuard {
27 Action &Actions;
28 void *Node;
29
30 void destroy() {
31 if (Node)
32 (Actions.*Destroyer)(Node);
33 }
34
35 ASTGuard(const ASTGuard&); // DO NOT IMPLEMENT
36 // Reference member prevents copy assignment.
37
38 public:
39 explicit ASTGuard(Action &actions) : Actions(actions), Node(0) {}
40 ASTGuard(Action &actions, void *node)
41 : Actions(actions), Node(node) {}
42 template <unsigned N>
43 ASTGuard(Action &actions, const Action::ActionResult<N> &res)
44 : Actions(actions), Node(res.Val) {}
45 ~ASTGuard() { destroy(); }
46
47 void reset(void *element) {
48 destroy();
49 Node = element;
50 }
51 template <unsigned N>
52 void reset(const Action::ActionResult<N> &res) {
53 reset(res.Val);
54 }
55 void *take() {
56 void *Temp = Node;
57 Node = 0;
58 return Temp;
59 }
60 void *get() const { return Node; }
61 };
62
63 typedef ASTGuard<&Action::DeleteStmt> StmtGuard;
64 typedef ASTGuard<&Action::DeleteExpr> ExprGuard;
65
66 /// RAII SmallVector wrapper that holds Action::ExprTy* and similar,
67 /// automatically freeing them on destruction unless it's been disowned.
68 /// Instantiated for statements and expressions (Action::DeleteStmt and
69 /// Action::DeleteExpr).
70 template <void (Action::*Destroyer)(void*), unsigned N>
71 class ASTVector : public llvm::SmallVector<void*, N> {
72 private:
73 Action &Actions;
74 bool Owns;
75
76 void destroy() {
77 if (Owns) {
78 while (!this->empty()) {
79 (Actions.*Destroyer)(this->back());
80 this->pop_back();
81 }
82 }
83 }
84
85 ASTVector(const ASTVector&); // DO NOT IMPLEMENT
86 // Reference member prevents copy assignment.
87
88 public:
89 ASTVector(Action &actions) : Actions(actions), Owns(true) {}
90
91 ~ASTVector() { destroy(); }
92
93 void **take() {
94 Owns = false;
95 return &(*this)[0];
96 }
97 };
98
99 /// A SmallVector of statements, with stack size 32 (as that is the only one
100 /// used.)
101 typedef ASTVector<&Action::DeleteStmt, 32> StmtVector;
102 /// A SmallVector of expressions, with stack size 12 (the maximum used.)
103 typedef ASTVector<&Action::DeleteExpr, 12> ExprVector;
104}
105
106#endif