summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/FullExpr.h
blob: 6ceefed8a63ab166febf5aa941f7b4306be9e502 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//===--- FullExpr.h - C++ full expression class -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the FullExpr interface, to be used for type safe handling
//  of full expressions.
//
//  Full expressions are described in C++ [intro.execution]p12.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_FULLEXPR_H
#define LLVM_CLANG_AST_FULLEXPR_H

#include "llvm/ADT/PointerUnion.h"

namespace clang {
  class ASTContext;
  class CXXTemporary;
  class Expr;

class FullExpr {
  struct ExprAndTemporaries {
    Expr *SubExpr;
    
    unsigned NumTemps;
    
    typedef CXXTemporary** temps_iterator;
    
    temps_iterator temps_begin() { 
      return reinterpret_cast<CXXTemporary **>(this + 1); 
    }
    temps_iterator temps_end() { 
      return temps_begin() + NumTemps;
    }
  };

  typedef llvm::PointerUnion<Expr *, ExprAndTemporaries *> SubExprTy;
  SubExprTy SubExpr;
  
  FullExpr() { }

public:
  static FullExpr Create(ASTContext &Context, Expr *SubExpr, 
                         CXXTemporary **Temps, unsigned NumTemps);
  
  Expr *getExpr() {
    if (Expr *E = SubExpr.dyn_cast<Expr *>())
      return E;
    
    return SubExpr.get<ExprAndTemporaries *>()->SubExpr;
  }
  
  const Expr *getExpr() const { 
    return const_cast<FullExpr*>(this)->getExpr();
  }
  
  typedef CXXTemporary** temps_iterator;

  temps_iterator temps_begin() {
    if (ExprAndTemporaries *ET = SubExpr.dyn_cast<ExprAndTemporaries *>())
      return ET->temps_begin();
    
    return 0;
  }
  temps_iterator temps_end() {
    if (ExprAndTemporaries *ET = SubExpr.dyn_cast<ExprAndTemporaries *>())
      return ET->temps_end();
    
    return 0;
  }
    
  void *getAsOpaquePtr() const { return SubExpr.getOpaqueValue(); }

  static FullExpr getFromOpaquePtr(void *Ptr) {
    FullExpr E;
    E.SubExpr = SubExprTy::getFromOpaqueValue(Ptr);
    return E;
  }
};

}  // end namespace clang

#endif
OpenPOWER on IntegriCloud