Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/AST/Interp/ByteCodeExprGen.cpp
Show First 20 Lines • Show All 1,235 Lines • ▼ Show 20 Lines | if (shouldBeGloballyIndexed(VD)) { | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
template <class Emitter> | template <class Emitter> | ||||
bool ByteCodeExprGen<Emitter>::VisitBuiltinCallExpr(const CallExpr *E) { | |||||
const Function *Func = getFunction(E->getDirectCallee()); | |||||
if (!Func) | |||||
return false; | |||||
// Put arguments on the stack. | |||||
for (const auto *Arg : E->arguments()) { | |||||
if (!this->visit(Arg)) | |||||
return false; | |||||
} | |||||
if (!this->emitCallBI(Func, E)) | |||||
return false; | |||||
if (DiscardResult) { | |||||
QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); | |||||
PrimType T = classifyPrim(ReturnType); | |||||
return this->emitPop(T, E); | |||||
} | |||||
return true; | |||||
} | |||||
template <class Emitter> | |||||
bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { | bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { | ||||
assert(!E->getBuiltinCallee() && "Builtin functions aren't supported yet"); | if (E->getBuiltinCallee()) | ||||
return VisitBuiltinCallExpr(E); | |||||
const Decl *Callee = E->getCalleeDecl(); | const Decl *Callee = E->getCalleeDecl(); | ||||
if (const auto *FuncDecl = dyn_cast_or_null<FunctionDecl>(Callee)) { | if (const auto *FuncDecl = dyn_cast_or_null<FunctionDecl>(Callee)) { | ||||
erichkeane: This is an unrelated change, perhaps could be in an NFC commit. | |||||
Right, sure tbaeder: Right, sure | |||||
const Function *Func = getFunction(FuncDecl); | const Function *Func = getFunction(FuncDecl); | ||||
if (!Func) | if (!Func) | ||||
return false; | return false; | ||||
// If the function is being compiled right now, this is a recursive call. | // If the function is being compiled right now, this is a recursive call. | ||||
// In that case, the function can't be valid yet, even though it will be | // In that case, the function can't be valid yet, even though it will be | ||||
// later. | // later. | ||||
// If the function is already fully compiled but not constexpr, it was | // If the function is already fully compiled but not constexpr, it was | ||||
// found to be faulty earlier on, so bail out. | // found to be faulty earlier on, so bail out. | ||||
Show All 14 Lines | if (const auto *FuncDecl = dyn_cast_or_null<FunctionDecl>(Callee)) { | ||||
} | } | ||||
// Put arguments on the stack. | // Put arguments on the stack. | ||||
for (const auto *Arg : E->arguments()) { | for (const auto *Arg : E->arguments()) { | ||||
if (!this->visit(Arg)) | if (!this->visit(Arg)) | ||||
return false; | return false; | ||||
} | } | ||||
// In any case call the function. The return value will end up on the stack and | // In any case call the function. The return value will end up on the stack | ||||
// if the function has RVO, we already have the pointer on the stack to write | // and if the function has RVO, we already have the pointer on the stack to | ||||
// the result into. | // write the result into. | ||||
if (!this->emitCall(Func, E)) | if (!this->emitCall(Func, E)) | ||||
return false; | return false; | ||||
if (DiscardResult && !ReturnType->isVoidType() && T) | if (DiscardResult && !ReturnType->isVoidType() && T) | ||||
return this->emitPop(*T, E); | return this->emitPop(*T, E); | ||||
return true; | return true; | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 214 Lines • Show Last 20 Lines |
This is an unrelated change, perhaps could be in an NFC commit.