clang  8.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  /// Whether we're in a constant context.
42  bool InConstantContext = false;
43 
44  /// The AST address space where this (non-abstract) initializer is going.
45  /// Used for generating appropriate placeholders.
46  LangAS DestAddressSpace;
47 
49  PlaceholderAddresses;
50 
51 public:
53  : CGM(CGM), CGF(CGF) {}
54 
55  /// Initialize this emission in the context of the given function.
56  /// Use this if the expression might contain contextual references like
57  /// block addresses or PredefinedExprs.
59  : CGM(CGF.CGM), CGF(&CGF) {}
60 
61  ConstantEmitter(const ConstantEmitter &other) = delete;
62  ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
63 
65 
66  /// Is the current emission context abstract?
67  bool isAbstract() const {
68  return Abstract;
69  }
70 
71  /// Try to emit the initiaizer of the given declaration as an abstract
72  /// constant. If this succeeds, the emission must be finalized.
73  llvm::Constant *tryEmitForInitializer(const VarDecl &D);
74  llvm::Constant *tryEmitForInitializer(const Expr *E, LangAS destAddrSpace,
75  QualType destType);
76  llvm::Constant *emitForInitializer(const APValue &value, LangAS destAddrSpace,
77  QualType destType);
78 
79  void finalize(llvm::GlobalVariable *global);
80 
81  // All of the "abstract" emission methods below permit the emission to
82  // be immediately discarded without finalizing anything. Therefore, they
83  // must also promise not to do anything that will, in the future, require
84  // finalization:
85  //
86  // - using the CGF (if present) for anything other than establishing
87  // semantic context; for example, an expression with ignored
88  // side-effects must not be emitted as an abstract expression
89  //
90  // - doing anything that would not be safe to duplicate within an
91  // initializer or to propagate to another context; for example,
92  // side effects, or emitting an initialization that requires a
93  // reference to its current location.
94 
95  /// Try to emit the initializer of the given declaration as an abstract
96  /// constant.
97  llvm::Constant *tryEmitAbstractForInitializer(const VarDecl &D);
98 
99  /// Emit the result of the given expression as an abstract constant,
100  /// asserting that it succeeded. This is only safe to do when the
101  /// expression is known to be a constant expression with either a fairly
102  /// simple type or a known simple form.
103  llvm::Constant *emitAbstract(const Expr *E, QualType T);
104  llvm::Constant *emitAbstract(SourceLocation loc, const APValue &value,
105  QualType T);
106 
107  /// Try to emit the result of the given expression as an abstract constant.
108  llvm::Constant *tryEmitAbstract(const Expr *E, QualType T);
109  llvm::Constant *tryEmitAbstractForMemory(const Expr *E, QualType T);
110 
111  llvm::Constant *tryEmitAbstract(const APValue &value, QualType T);
112  llvm::Constant *tryEmitAbstractForMemory(const APValue &value, QualType T);
113 
114  llvm::Constant *emitNullForMemory(QualType T) {
115  return emitNullForMemory(CGM, T);
116  }
117  llvm::Constant *emitForMemory(llvm::Constant *C, QualType T) {
118  return emitForMemory(CGM, C, T);
119  }
120 
121  static llvm::Constant *emitNullForMemory(CodeGenModule &CGM, QualType T);
122  static llvm::Constant *emitForMemory(CodeGenModule &CGM, llvm::Constant *C,
123  QualType T);
124 
125  // These are private helper routines of the constant emitter that
126  // can't actually be private because things are split out into helper
127  // functions and classes.
128 
129  llvm::Constant *tryEmitPrivateForVarInit(const VarDecl &D);
130 
131  llvm::Constant *tryEmitPrivate(const Expr *E, QualType T);
132  llvm::Constant *tryEmitPrivateForMemory(const Expr *E, QualType T);
133 
134  llvm::Constant *tryEmitPrivate(const APValue &value, QualType T);
135  llvm::Constant *tryEmitPrivateForMemory(const APValue &value, QualType T);
136 
137  /// Get the address of the current location. This is a constant
138  /// that will resolve, after finalization, to the address of the
139  /// 'signal' value that is registered with the emitter later.
140  llvm::GlobalValue *getCurrentAddrPrivate();
141 
142  /// Register a 'signal' value with the emitter to inform it where to
143  /// resolve a placeholder. The signal value must be unique in the
144  /// initializer; it might, for example, be the address of a global that
145  /// refers to the current-address value in its own initializer.
146  ///
147  /// Uses of the placeholder must be properly anchored before finalizing
148  /// the emitter, e.g. by being installed as the initializer of a global
149  /// variable. That is, it must be possible to replaceAllUsesWith
150  /// the placeholder with the proper address of the signal.
151  void registerCurrentAddrPrivate(llvm::Constant *signal,
152  llvm::GlobalValue *placeholder);
153 
154 private:
155  void initializeNonAbstract(LangAS destAS) {
156  assert(!InitializedNonAbstract);
157  InitializedNonAbstract = true;
158  DestAddressSpace = destAS;
159  }
160  llvm::Constant *markIfFailed(llvm::Constant *init) {
161  if (!init)
162  Failed = true;
163  return init;
164  }
165 
166  struct AbstractState {
167  bool OldValue;
168  size_t OldPlaceholdersSize;
169  };
170  AbstractState pushAbstract() {
171  AbstractState saved = { Abstract, PlaceholderAddresses.size() };
172  Abstract = true;
173  return saved;
174  }
175  llvm::Constant *validateAndPopAbstract(llvm::Constant *C, AbstractState save);
176 };
177 
178 }
179 }
180 
181 #endif
A (possibly-)qualified type.
Definition: Type.h:638
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)
Represents a variable declaration or definition.
Definition: Decl.h:812
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.
This represents one expression.
Definition: Expr.h:106
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)