clang  6.0.0svn
ConstantEmitter.h
Go to the documentation of this file.
1 //===--- ConstantEmitter.h - IR constant emission ---------------*- 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 // A helper class for emitting expressions and values as llvm::Constants
11 // and as initializers for global variables.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
16 #define LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
17 
18 #include "CodeGenFunction.h"
19 #include "CodeGenModule.h"
20 
21 namespace clang {
22 namespace CodeGen {
23 
25 public:
28 
29 private:
30  bool Abstract = false;
31 
32  /// Whether non-abstract components of the emitter have been initialized.
33  bool InitializedNonAbstract = false;
34 
35  /// Whether the emitter has been finalized.
36  bool Finalized = false;
37 
38  /// Whether the constant-emission failed.
39  bool Failed = false;
40 
41  /// The AST address space where this (non-abstract) initializer is going.
42  /// Used for generating appropriate placeholders.
43  LangAS DestAddressSpace;
44 
46  PlaceholderAddresses;
47 
48 public:
50  : CGM(CGM), CGF(CGF) {}
51 
52  /// Initialize this emission in the context of the given function.
53  /// Use this if the expression might contain contextaul references like
54  /// block addresses or PredefinedExprs.
56  : CGM(CGF.CGM), CGF(&CGF) {}
57 
58  ConstantEmitter(const ConstantEmitter &other) = delete;
59  ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
60 
62 
63  /// Is the current emission context abstract?
64  bool isAbstract() const {
65  return Abstract;
66  }
67 
68  /// Try to emit the initiaizer of the given declaration as an abstract
69  /// constant. If this succeeds, the emission must be finalized.
70  llvm::Constant *tryEmitForInitializer(const VarDecl &D);
71  llvm::Constant *tryEmitForInitializer(const Expr *E, LangAS destAddrSpace,
72  QualType destType);
73  llvm::Constant *emitForInitializer(const APValue &value, LangAS destAddrSpace,
74  QualType destType);
75 
76  void finalize(llvm::GlobalVariable *global);
77 
78  // All of the "abstract" emission methods below permit the emission to
79  // be immediately discarded without finalizing anything. Therefore, they
80  // must also promise not to do anything that will, in the future, require
81  // finalization:
82  //
83  // - using the CGF (if present) for anything other than establishing
84  // semantic context; for example, an expression with ignored
85  // side-effects must not be emitted as an abstract expression
86  //
87  // - doing anything that would not be safe to duplicate within an
88  // initializer or to propagate to another context; for example,
89  // side effects, or emitting an initialization that requires a
90  // reference to its current location.
91 
92  /// Try to emit the initializer of the given declaration as an abstract
93  /// constant.
94  llvm::Constant *tryEmitAbstractForInitializer(const VarDecl &D);
95 
96  /// Emit the result of the given expression as an abstract constant,
97  /// asserting that it succeeded. This is only safe to do when the
98  /// expression is known to be a constant expression with either a fairly
99  /// simple type or a known simple form.
100  llvm::Constant *emitAbstract(const Expr *E, QualType T);
101  llvm::Constant *emitAbstract(SourceLocation loc, const APValue &value,
102  QualType T);
103 
104  /// Try to emit the result of the given expression as an abstract constant.
105  llvm::Constant *tryEmitAbstract(const Expr *E, QualType T);
106  llvm::Constant *tryEmitAbstractForMemory(const Expr *E, QualType T);
107 
108  llvm::Constant *tryEmitAbstract(const APValue &value, QualType T);
109  llvm::Constant *tryEmitAbstractForMemory(const APValue &value, QualType T);
110 
111  llvm::Constant *emitNullForMemory(QualType T) {
112  return emitNullForMemory(CGM, T);
113  }
114  llvm::Constant *emitForMemory(llvm::Constant *C, QualType T) {
115  return emitForMemory(CGM, C, T);
116  }
117 
118  static llvm::Constant *emitNullForMemory(CodeGenModule &CGM, QualType T);
119  static llvm::Constant *emitForMemory(CodeGenModule &CGM, llvm::Constant *C,
120  QualType T);
121 
122  // These are private helper routines of the constant emitter that
123  // can't actually be private because things are split out into helper
124  // functions and classes.
125 
126  llvm::Constant *tryEmitPrivateForVarInit(const VarDecl &D);
127 
128  llvm::Constant *tryEmitPrivate(const Expr *E, QualType T);
129  llvm::Constant *tryEmitPrivateForMemory(const Expr *E, QualType T);
130 
131  llvm::Constant *tryEmitPrivate(const APValue &value, QualType T);
132  llvm::Constant *tryEmitPrivateForMemory(const APValue &value, QualType T);
133 
134  /// Get the address of the current location. This is a constant
135  /// that will resolve, after finalization, to the address of the
136  /// 'signal' value that is registered with the emitter later.
137  llvm::GlobalValue *getCurrentAddrPrivate();
138 
139  /// Register a 'signal' value with the emitter to inform it where to
140  /// resolve a placeholder. The signal value must be unique in the
141  /// initializer; it might, for example, be the address of a global that
142  /// refers to the current-address value in its own initializer.
143  ///
144  /// Uses of the placeholder must be properly anchored before finalizing
145  /// the emitter, e.g. by being installed as the initializer of a global
146  /// variable. That is, it must be possible to replaceAllUsesWith
147  /// the placeholder with the proper address of the signal.
148  void registerCurrentAddrPrivate(llvm::Constant *signal,
149  llvm::GlobalValue *placeholder);
150 
151 private:
152  void initializeNonAbstract(LangAS destAS) {
153  assert(!InitializedNonAbstract);
154  InitializedNonAbstract = true;
155  DestAddressSpace = destAS;
156  }
157  llvm::Constant *markIfFailed(llvm::Constant *init) {
158  if (!init)
159  Failed = true;
160  return init;
161  }
162 
163  struct AbstractState {
164  bool OldValue;
165  size_t OldPlaceholdersSize;
166  };
167  AbstractState pushAbstract() {
168  AbstractState saved = { Abstract, PlaceholderAddresses.size() };
169  Abstract = true;
170  return saved;
171  }
172  llvm::Constant *validateAndPopAbstract(llvm::Constant *C, AbstractState save);
173 };
174 
175 }
176 }
177 
178 #endif
A (possibly-)qualified type.
Definition: Type.h:614
llvm::Constant * emitForInitializer(const APValue &value, LangAS destAddrSpace, QualType destType)
llvm::Constant * tryEmitForInitializer(const VarDecl &D)
Try to emit the initiaizer of the given declaration as an abstract constant.
llvm::Constant * emitForMemory(llvm::Constant *C, QualType T)
llvm::Constant * tryEmitPrivateForVarInit(const VarDecl &D)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:771
LangAS
Defines the address space values used by the address space qualifier of QualType. ...
Definition: AddressSpaces.h:26
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
ConstantEmitter & operator=(const ConstantEmitter &other)=delete
ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF=nullptr)
llvm::Constant * tryEmitPrivate(const Expr *E, QualType T)
llvm::GlobalValue * getCurrentAddrPrivate()
Get the address of the current location.
ConstantEmitter(CodeGenFunction &CGF)
Initialize this emission in the context of the given function.
Expr - This represents one expression.
Definition: Expr.h:106
const FunctionProtoType * T
Encodes a location in the source.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded...
void registerCurrentAddrPrivate(llvm::Constant *signal, llvm::GlobalValue *placeholder)
Register a 'signal' value with the emitter to inform it where to resolve a placeholder.
llvm::Constant * emitNullForMemory(QualType T)
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
llvm::Constant * tryEmitPrivateForMemory(const Expr *E, QualType T)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Definition: APValue.h:38
void finalize(llvm::GlobalVariable *global)
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
bool isAbstract() const
Is the current emission context abstract?
llvm::Constant * tryEmitAbstractForMemory(const Expr *E, QualType T)