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 24 class ConstantEmitter { 25 public: 26 CodeGenModule &CGM; 27 CodeGenFunction *CGF; 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 45 llvm::SmallVector<std::pair<llvm::Constant *, llvm::GlobalVariable*>, 4> 46 PlaceholderAddresses; 47 48 public: 49 ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF = nullptr) CGM(CGM)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 contextual references like 54 /// block addresses or PredefinedExprs. ConstantEmitter(CodeGenFunction & CGF)55 ConstantEmitter(CodeGenFunction &CGF) 56 : CGM(CGF.CGM), CGF(&CGF) {} 57 58 ConstantEmitter(const ConstantEmitter &other) = delete; 59 ConstantEmitter &operator=(const ConstantEmitter &other) = delete; 60 61 ~ConstantEmitter(); 62 63 /// Is the current emission context abstract? isAbstract()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 emitNullForMemory(QualType T)111 llvm::Constant *emitNullForMemory(QualType T) { 112 return emitNullForMemory(CGM, T); 113 } emitForMemory(llvm::Constant * C,QualType T)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: initializeNonAbstract(LangAS destAS)152 void initializeNonAbstract(LangAS destAS) { 153 assert(!InitializedNonAbstract); 154 InitializedNonAbstract = true; 155 DestAddressSpace = destAS; 156 } markIfFailed(llvm::Constant * init)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 }; pushAbstract()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 179