aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/Interp/Program.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/Program.h')
-rw-r--r--clang/lib/AST/Interp/Program.h54
1 files changed, 35 insertions, 19 deletions
diff --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h
index ca985af8ad30..5a80dd1ed748 100644
--- a/clang/lib/AST/Interp/Program.h
+++ b/clang/lib/AST/Interp/Program.h
@@ -37,10 +37,26 @@ class Context;
class Record;
/// The program contains and links the bytecode for all functions.
-class Program {
+class Program final {
public:
Program(Context &Ctx) : Ctx(Ctx) {}
+ ~Program() {
+ // Manually destroy all the blocks. They are almost all harmless,
+ // but primitive arrays might have an InitMap* heap allocated and
+ // that needs to be freed.
+ for (Global *G : Globals)
+ G->block()->invokeDtor();
+
+ // Records might actually allocate memory themselves, but they
+ // are allocated using a BumpPtrAllocator. Call their desctructors
+ // here manually so they are properly freeing their resources.
+ for (auto RecordPair : Records) {
+ if (Record *R = RecordPair.second)
+ R->~Record();
+ }
+ }
+
/// Marshals a native pointer to an ID for embedding in bytecode.
unsigned getOrCreateNativePointer(const void *Ptr);
@@ -60,23 +76,25 @@ public:
}
/// Finds a global's index.
- llvm::Optional<unsigned> getGlobal(const ValueDecl *VD);
+ std::optional<unsigned> getGlobal(const ValueDecl *VD);
/// Returns or creates a global an creates an index to it.
- llvm::Optional<unsigned> getOrCreateGlobal(const ValueDecl *VD);
+ std::optional<unsigned> getOrCreateGlobal(const ValueDecl *VD,
+ const Expr *Init = nullptr);
/// Returns or creates a dummy value for parameters.
- llvm::Optional<unsigned> getOrCreateDummy(const ParmVarDecl *PD);
+ std::optional<unsigned> getOrCreateDummy(const ParmVarDecl *PD);
/// Creates a global and returns its index.
- llvm::Optional<unsigned> createGlobal(const ValueDecl *VD);
+ std::optional<unsigned> createGlobal(const ValueDecl *VD, const Expr *E);
/// Creates a global from a lifetime-extended temporary.
- llvm::Optional<unsigned> createGlobal(const Expr *E);
+ std::optional<unsigned> createGlobal(const Expr *E);
/// Creates a new function from a code range.
template <typename... Ts>
Function *createFunction(const FunctionDecl *Def, Ts &&... Args) {
+ Def = Def->getCanonicalDecl();
auto *Func = new Function(*this, Def, std::forward<Ts>(Args)...);
Funcs.insert({Def, std::unique_ptr<Function>(Func)});
return Func;
@@ -92,26 +110,23 @@ public:
/// Returns a function.
Function *getFunction(const FunctionDecl *F);
- /// Returns a pointer to a function if it exists and can be compiled.
- /// If a function couldn't be compiled, an error is returned.
- /// If a function was not yet defined, a null pointer is returned.
- llvm::Expected<Function *> getOrCreateFunction(const FunctionDecl *F);
-
/// Returns a record or creates one if it does not exist.
Record *getOrCreateRecord(const RecordDecl *RD);
/// Creates a descriptor for a primitive type.
Descriptor *createDescriptor(const DeclTy &D, PrimType Type,
- bool IsConst = false,
- bool IsTemporary = false,
+ Descriptor::MetadataSize MDSize = std::nullopt,
+ bool IsConst = false, bool IsTemporary = false,
bool IsMutable = false) {
- return allocateDescriptor(D, Type, IsConst, IsTemporary, IsMutable);
+ return allocateDescriptor(D, Type, MDSize, IsConst, IsTemporary, IsMutable);
}
/// Creates a descriptor for a composite type.
Descriptor *createDescriptor(const DeclTy &D, const Type *Ty,
+ Descriptor::MetadataSize MDSize = std::nullopt,
bool IsConst = false, bool IsTemporary = false,
- bool IsMutable = false);
+ bool IsMutable = false,
+ const Expr *Init = nullptr);
/// Context to manage declaration lifetimes.
class DeclScope {
@@ -124,17 +139,18 @@ public:
};
/// Returns the current declaration ID.
- llvm::Optional<unsigned> getCurrentDecl() const {
+ std::optional<unsigned> getCurrentDecl() const {
if (CurrentDeclaration == NoDeclaration)
- return llvm::Optional<unsigned>{};
+ return std::optional<unsigned>{};
return LastDeclaration;
}
private:
friend class DeclScope;
- llvm::Optional<unsigned> createGlobal(const DeclTy &D, QualType Ty,
- bool IsStatic, bool IsExtern);
+ std::optional<unsigned> createGlobal(const DeclTy &D, QualType Ty,
+ bool IsStatic, bool IsExtern,
+ const Expr *Init = nullptr);
/// Reference to the VM context.
Context &Ctx;