[PATCH] D37035: Implement __builtin_LINE() et. al. to support source location capture.
Richard Smith - zygoloid via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 7 16:23:00 PST 2019
rsmith added inline comments.
================
Comment at: include/clang/AST/ASTContext.h:279
+ /// A cache mapping a function declaration to its human-readable function or
+ /// file name.
----------------
Comment seems out of date: the key here is a string rather than a function declaration.
================
Comment at: lib/AST/Expr.cpp:2012-2020
+ case SourceLocExpr::Function:
+ case SourceLocExpr::File: {
+ return [&]() {
+ auto MkStr = [&](StringRef Tmp) {
+ StringLiteral *Res = Ctx.getPredefinedStringLiteralFromCache(Tmp);
+ return APValue(Res, CharUnits::Zero(), APValue::NoLValuePath(), 0);
+ };
----------------
Combining these two cases doesn't really make sense since they have nothing in common (except that both produce strings). Instead, consider hoisting the `MkStr` lambda out of the switch and separating the cases.
================
Comment at: lib/AST/Expr.cpp:2022-2023
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(Context);
+ if (!FD)
+ return MkStr("");
+ // If we have a simple identifier there is no need to cache the
----------------
Why not call into `PredefinedExpr` for the other cases that `__FUNCTION__` supports (`BlockDecl`, `CapturedDecl`, `ObjCMethodDecl`)?
================
Comment at: lib/AST/Expr.cpp:2026-2027
+ // human readable name.
+ if (IdentifierInfo *II = FD->getDeclName().getAsIdentifierInfo())
+ return MkStr(II->getNameStart());
+ return MkStr(PredefinedExpr::ComputeName(PredefinedExpr::Function, FD));
----------------
Is the benefit of avoiding a `std::string` allocation here really worth the cost of duplicating this portion of the `__FUNCTION__` logic?
If we care about the extra string allocation, it'd seem more worthwhile to extend `ComputeName` so that a stack-allocated `SmallString<N>` buffer can be passed in (eg, `StringRef ComputeName(..., SmallVectorImpl<char> &NameStorage)`, where `NameStorage` may, but need not, be used to store the resulting string).
================
Comment at: lib/AST/ExprConstant.cpp:2653-2655
+ APValue::LValueBase const &Base,
uint64_t Index) {
+ const Expr *Lit = Base.get<const Expr *>();
----------------
Hm, why the move of the `get` from caller to callee? This widens the set of possible arguments to `extractStringLiteralCharacter`, but all the new possibilities result in crashes -- shouldn't the caller, rather than the callee, still be the place where we house the assertion that the base is indeed an expression?
================
Comment at: lib/AST/ExprConstant.cpp:3370-3371
+
+ assert((!Base || !isa<SourceLocExpr>(Base)) &&
+ "Base should have already been transformed into a StringLiteral");
+
----------------
There are lots of forms of expression that cannot be the base of an `LValue` (see the list above `LValueExprEvaluator` for the expression forms that *can* be the base of an `LValue`); is it important to give this one special treatment?
================
Comment at: lib/CodeGen/CGExprConstant.cpp:1762
+ConstantLValue
+ConstantLValueEmitter::VisitSourceLocExpr(const SourceLocExpr *E) {
+ const APValue::LValueBase& Base = Value.getLValueBase();
----------------
Hmm, is this reachable? I thought `SourceLocExpr` was always a prvalue.
================
Comment at: lib/CodeGen/CGExprConstant.cpp:1766
+ "Expected string literal result");
+ const StringLiteral* Str = cast<StringLiteral>(Base.get<const Expr*>());
+
----------------
`const auto *Str`
================
Comment at: lib/CodeGen/CGExprConstant.cpp:1768-1769
+
+ // assert(Base.isGlobalString() &&
+ // "source location expression does not evaluate to global string?");
+ return CGM.GetAddrOfConstantCString(Str->getBytes());
----------------
Please remove or uncomment this.
================
Comment at: lib/Sema/TreeTransform.h:9990
+ bool NeedRebuildFunc = E->getIdentType() == SourceLocExpr::Function &&
+ isa<FunctionDecl>(getSema().CurContext) &&
+ getSema().CurContext != E->getParentContext();
----------------
If we generalize `__builtin_FUNCTION()` to behave like `__FUNCTION__` (and handle function-like contexts that aren't `FunctionDecl`s), this `isa` check will be wrong.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D37035/new/
https://reviews.llvm.org/D37035
More information about the cfe-commits
mailing list