Phase 3f complete: Advanced Memory Management (Steps 64-67)
Step 64: AnnotationValidator — @Deallocate missing-intent, @Owner(Single) alias detection, parent/child conflict (5/5 tests) Step 65: MemoryStrategyInference — language defaults, per-function pattern analysis, confidence scores (5/5 tests) Step 66: CrossLanguageProjector — deep-copy AST projection, annotation-aware CppGenerator (shared_ptr/unique_ptr) (5/5 tests) Step 67: Optimization annotations — HotCold, Inline, Pure, ConstExpr with C++ attribute generation (9/9 tests) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -107,8 +107,8 @@ class AllocateAnnotation : public Annotation {
|
||||
public:
|
||||
std::string strategy; // "Static", "Register", "Allocator" for allocation strategies
|
||||
std::string allocationPattern;
|
||||
AllocateAnnotation() {
|
||||
conceptType = "AllocateAnnotation";
|
||||
AllocateAnnotation() {
|
||||
conceptType = "AllocateAnnotation";
|
||||
strategy = "Static";
|
||||
}
|
||||
AllocateAnnotation(const std::string& id, const std::string& strategy_val)
|
||||
@@ -117,3 +117,27 @@ public:
|
||||
this->conceptType = "AllocateAnnotation";
|
||||
}
|
||||
};
|
||||
|
||||
// Optimization annotations (Step 67)
|
||||
|
||||
class HotColdAnnotation : public Annotation {
|
||||
public:
|
||||
std::string hint; // "Hot" or "Cold"
|
||||
HotColdAnnotation() { conceptType = "HotColdAnnotation"; }
|
||||
};
|
||||
|
||||
class InlineAnnotation : public Annotation {
|
||||
public:
|
||||
std::string mode; // "Always", "Never", "Hint"
|
||||
InlineAnnotation() { conceptType = "InlineAnnotation"; }
|
||||
};
|
||||
|
||||
class PureAnnotation : public Annotation {
|
||||
public:
|
||||
PureAnnotation() { conceptType = "PureAnnotation"; }
|
||||
};
|
||||
|
||||
class ConstExprAnnotation : public Annotation {
|
||||
public:
|
||||
ConstExprAnnotation() { conceptType = "ConstExprAnnotation"; }
|
||||
};
|
||||
|
||||
@@ -57,6 +57,10 @@ public:
|
||||
virtual std::string visitReclaimAnnotation(const ReclaimAnnotation* annotation) = 0;
|
||||
virtual std::string visitOwnerAnnotation(const OwnerAnnotation* annotation) = 0;
|
||||
virtual std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) = 0;
|
||||
virtual std::string visitHotColdAnnotation(const HotColdAnnotation* annotation) = 0;
|
||||
virtual std::string visitInlineAnnotation(const InlineAnnotation* annotation) = 0;
|
||||
virtual std::string visitPureAnnotation(const PureAnnotation* annotation) = 0;
|
||||
virtual std::string visitConstExprAnnotation(const ConstExprAnnotation* annotation) = 0;
|
||||
};
|
||||
|
||||
class PythonGenerator : public ProjectionGenerator {
|
||||
@@ -142,14 +146,22 @@ public:
|
||||
return visitOwnerAnnotation(static_cast<const OwnerAnnotation*>(node));
|
||||
} else if (node->conceptType == "AllocateAnnotation") {
|
||||
return visitAllocateAnnotation(static_cast<const AllocateAnnotation*>(node));
|
||||
} else if (node->conceptType == "HotColdAnnotation") {
|
||||
return visitHotColdAnnotation(static_cast<const HotColdAnnotation*>(node));
|
||||
} else if (node->conceptType == "InlineAnnotation") {
|
||||
return visitInlineAnnotation(static_cast<const InlineAnnotation*>(node));
|
||||
} else if (node->conceptType == "PureAnnotation") {
|
||||
return visitPureAnnotation(static_cast<const PureAnnotation*>(node));
|
||||
} else if (node->conceptType == "ConstExprAnnotation") {
|
||||
return visitConstExprAnnotation(static_cast<const ConstExprAnnotation*>(node));
|
||||
}
|
||||
|
||||
|
||||
return "// Unknown concept: " + node->conceptType;
|
||||
}
|
||||
|
||||
std::string visitModule(const Module* module) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
|
||||
// Add module docstring and basic info
|
||||
oss << "\"\"\"Module: " << module->name << "\"\"\"\n\n";
|
||||
|
||||
@@ -697,6 +709,22 @@ public:
|
||||
std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) override {
|
||||
return "# @allocate(" + annotation->strategy + ") - Memory allocation strategy";
|
||||
}
|
||||
|
||||
std::string visitHotColdAnnotation(const HotColdAnnotation* annotation) override {
|
||||
return "# @" + annotation->hint + " - Optimization hint";
|
||||
}
|
||||
|
||||
std::string visitInlineAnnotation(const InlineAnnotation* annotation) override {
|
||||
return "# @inline(" + annotation->mode + ")";
|
||||
}
|
||||
|
||||
std::string visitPureAnnotation(const PureAnnotation*) override {
|
||||
return "# @pure - No side effects";
|
||||
}
|
||||
|
||||
std::string visitConstExprAnnotation(const ConstExprAnnotation*) override {
|
||||
return "# @constexpr - Compile-time evaluable";
|
||||
}
|
||||
};
|
||||
|
||||
class ElispGenerator : public ProjectionGenerator {
|
||||
@@ -772,8 +800,26 @@ public:
|
||||
return visitOptimizationLock(static_cast<const OptimizationLock*>(node));
|
||||
} else if (node->conceptType == "LangSpecific") {
|
||||
return visitLangSpecific(static_cast<const LangSpecific*>(node));
|
||||
} else if (node->conceptType == "DeallocateAnnotation") {
|
||||
return visitDeallocateAnnotation(static_cast<const DeallocateAnnotation*>(node));
|
||||
} else if (node->conceptType == "LifetimeAnnotation") {
|
||||
return visitLifetimeAnnotation(static_cast<const LifetimeAnnotation*>(node));
|
||||
} else if (node->conceptType == "ReclaimAnnotation") {
|
||||
return visitReclaimAnnotation(static_cast<const ReclaimAnnotation*>(node));
|
||||
} else if (node->conceptType == "OwnerAnnotation") {
|
||||
return visitOwnerAnnotation(static_cast<const OwnerAnnotation*>(node));
|
||||
} else if (node->conceptType == "AllocateAnnotation") {
|
||||
return visitAllocateAnnotation(static_cast<const AllocateAnnotation*>(node));
|
||||
} else if (node->conceptType == "HotColdAnnotation") {
|
||||
return visitHotColdAnnotation(static_cast<const HotColdAnnotation*>(node));
|
||||
} else if (node->conceptType == "InlineAnnotation") {
|
||||
return visitInlineAnnotation(static_cast<const InlineAnnotation*>(node));
|
||||
} else if (node->conceptType == "PureAnnotation") {
|
||||
return visitPureAnnotation(static_cast<const PureAnnotation*>(node));
|
||||
} else if (node->conceptType == "ConstExprAnnotation") {
|
||||
return visitConstExprAnnotation(static_cast<const ConstExprAnnotation*>(node));
|
||||
}
|
||||
|
||||
|
||||
return "; Unknown concept: " + node->conceptType;
|
||||
}
|
||||
|
||||
@@ -1296,6 +1342,22 @@ public:
|
||||
std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) override {
|
||||
return "; @allocate(" + annotation->strategy + ")";
|
||||
}
|
||||
|
||||
std::string visitHotColdAnnotation(const HotColdAnnotation* annotation) override {
|
||||
return "; @" + annotation->hint + " - Optimization hint";
|
||||
}
|
||||
|
||||
std::string visitInlineAnnotation(const InlineAnnotation* annotation) override {
|
||||
return "; @inline(" + annotation->mode + ")";
|
||||
}
|
||||
|
||||
std::string visitPureAnnotation(const PureAnnotation*) override {
|
||||
return "; @pure - No side effects";
|
||||
}
|
||||
|
||||
std::string visitConstExprAnnotation(const ConstExprAnnotation*) override {
|
||||
return "; @constexpr - Compile-time evaluable";
|
||||
}
|
||||
};
|
||||
|
||||
class CppGenerator : public ProjectionGenerator {
|
||||
@@ -1381,8 +1443,16 @@ public:
|
||||
return visitOwnerAnnotation(static_cast<const OwnerAnnotation*>(node));
|
||||
} else if (node->conceptType == "AllocateAnnotation") {
|
||||
return visitAllocateAnnotation(static_cast<const AllocateAnnotation*>(node));
|
||||
} else if (node->conceptType == "HotColdAnnotation") {
|
||||
return visitHotColdAnnotation(static_cast<const HotColdAnnotation*>(node));
|
||||
} else if (node->conceptType == "InlineAnnotation") {
|
||||
return visitInlineAnnotation(static_cast<const InlineAnnotation*>(node));
|
||||
} else if (node->conceptType == "PureAnnotation") {
|
||||
return visitPureAnnotation(static_cast<const PureAnnotation*>(node));
|
||||
} else if (node->conceptType == "ConstExprAnnotation") {
|
||||
return visitConstExprAnnotation(static_cast<const ConstExprAnnotation*>(node));
|
||||
}
|
||||
|
||||
|
||||
return "// Unknown concept: " + node->conceptType;
|
||||
}
|
||||
|
||||
@@ -1478,42 +1548,48 @@ public:
|
||||
|
||||
std::string visitVariable(const Variable* variable) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
|
||||
auto type = variable->getChild("type");
|
||||
std::string typeStr = "auto"; // Default
|
||||
if (type) {
|
||||
typeStr = generate(type);
|
||||
}
|
||||
|
||||
oss << typeStr << " " << variable->name;
|
||||
|
||||
|
||||
// Check enclosing function for memory annotations that affect variable types
|
||||
std::string wrapper = getMemoryTypeWrapper(variable);
|
||||
if (!wrapper.empty()) {
|
||||
oss << wrapper << "<" << typeStr << "> " << variable->name;
|
||||
} else {
|
||||
oss << typeStr << " " << variable->name;
|
||||
}
|
||||
|
||||
auto initializer = variable->getChild("initializer");
|
||||
if (initializer) {
|
||||
oss << " = " << generate(initializer);
|
||||
}
|
||||
|
||||
|
||||
oss << ";";
|
||||
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string visitParameter(const Parameter* parameter) override {
|
||||
std::ostringstream oss;
|
||||
|
||||
|
||||
auto type = parameter->getChild("type");
|
||||
std::string typeStr = "auto"; // Default
|
||||
if (type) {
|
||||
typeStr = generate(type);
|
||||
}
|
||||
|
||||
|
||||
oss << typeStr << " " << parameter->name;
|
||||
|
||||
|
||||
// Add default value if present
|
||||
auto defaultValue = parameter->getChild("defaultValue");
|
||||
if (defaultValue) {
|
||||
oss << " = " << generate(defaultValue);
|
||||
}
|
||||
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
@@ -2019,4 +2095,57 @@ public:
|
||||
std::string visitAllocateAnnotation(const AllocateAnnotation* annotation) override {
|
||||
return "// @allocate(" + annotation->strategy + ") - Memory allocation strategy";
|
||||
}
|
||||
|
||||
std::string visitHotColdAnnotation(const HotColdAnnotation* annotation) override {
|
||||
if (annotation->hint == "Hot")
|
||||
return "__attribute__((hot))";
|
||||
if (annotation->hint == "Cold")
|
||||
return "__attribute__((cold))";
|
||||
return "// @hotcold(" + annotation->hint + ")";
|
||||
}
|
||||
|
||||
std::string visitInlineAnnotation(const InlineAnnotation* annotation) override {
|
||||
if (annotation->mode == "Always")
|
||||
return "[[gnu::always_inline]] inline";
|
||||
if (annotation->mode == "Never")
|
||||
return "__attribute__((noinline))";
|
||||
return "inline";
|
||||
}
|
||||
|
||||
std::string visitPureAnnotation(const PureAnnotation*) override {
|
||||
return "[[nodiscard]]";
|
||||
}
|
||||
|
||||
std::string visitConstExprAnnotation(const ConstExprAnnotation*) override {
|
||||
return "constexpr";
|
||||
}
|
||||
|
||||
private:
|
||||
// Check enclosing function's memory annotations to determine smart-pointer wrapper
|
||||
std::string getMemoryTypeWrapper(const Variable* variable) const {
|
||||
const ASTNode* cur = variable->parent;
|
||||
while (cur && cur->conceptType != "Function") {
|
||||
cur = cur->parent;
|
||||
}
|
||||
if (!cur) return "";
|
||||
|
||||
for (auto* anno : cur->getChildren("annotations")) {
|
||||
if (anno->conceptType == "ReclaimAnnotation") {
|
||||
auto* ra = static_cast<const ReclaimAnnotation*>(anno);
|
||||
if (ra->strategy == "Tracing" || ra->strategy == "Cycle")
|
||||
return "std::shared_ptr";
|
||||
}
|
||||
if (anno->conceptType == "LifetimeAnnotation") {
|
||||
auto* la = static_cast<const LifetimeAnnotation*>(anno);
|
||||
if (la->strategy == "RAII")
|
||||
return "std::unique_ptr";
|
||||
}
|
||||
if (anno->conceptType == "OwnerAnnotation") {
|
||||
auto* oa = static_cast<const OwnerAnnotation*>(anno);
|
||||
if (oa->strategy == "Shared_ARC") return "std::shared_ptr";
|
||||
if (oa->strategy == "Single") return "std::unique_ptr";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user