[cfe-commits] r81383 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/CodeGen/CGCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp
Anders Carlsson
andersca at mac.com
Wed Sep 9 14:33:22 PDT 2009
Author: andersca
Date: Wed Sep 9 16:33:21 2009
New Revision: 81383
URL: http://llvm.org/viewvc/llvm-project?rev=81383&view=rev
Log:
If a cast expression needs either a conversion function or a constructor to be called, generate implicit child expressions that call them.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCXXCast.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Sep 9 16:33:21 2009
@@ -550,20 +550,16 @@
/// that uses "functional" notion (C++ [expr.type.conv]). Example: @c
/// x = int(0.5);
class CXXFunctionalCastExpr : public ExplicitCastExpr {
- CXXMethodDecl *TypeConversionMethod;
SourceLocation TyBeginLoc;
SourceLocation RParenLoc;
public:
CXXFunctionalCastExpr(QualType ty, QualType writtenTy,
SourceLocation tyBeginLoc, CastKind kind,
- Expr *castExpr, CXXMethodDecl *typeConversionMethod,
- SourceLocation rParenLoc) :
- ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, writtenTy),
- TypeConversionMethod(typeConversionMethod),
- TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+ Expr *castExpr, SourceLocation rParenLoc)
+ : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr,
+ writtenTy),
+ TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
- CXXMethodDecl *getTypeConversionMethod() const
- { return TypeConversionMethod; }
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Wed Sep 9 16:33:21 2009
@@ -264,28 +264,6 @@
E->arg_begin() + 1, E->arg_end());
}
-RValue
-CodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) {
- assert((E->getCastKind() == CastExpr::CK_UserDefinedConversion) &&
- "EmitCXXFunctionalCastExpr - called with wrong cast");
-
- CXXMethodDecl *MD = E->getTypeConversionMethod();
- assert(MD && "EmitCXXFunctionalCastExpr - null conversion method");
- assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not"
- " method decl");
- const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
-
- const llvm::Type *Ty =
- CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
- FPT->isVariadic());
- llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
- llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress();
- RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0);
- if (RV.isAggregate())
- RV = RValue::get(RV.getAggregateAddr());
- return RV;
-}
-
llvm::Value *CodeGenFunction::LoadCXXThis() {
assert(isa<CXXMethodDecl>(CurFuncDecl) &&
"Must be in a C++ member function decl to load 'this'");
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Sep 9 16:33:21 2009
@@ -1158,19 +1158,11 @@
/// all the reasons that casts are permitted with aggregate result, including
/// noop aggregate casts, and cast from scalar to union.
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
- if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
- if (const CXXFunctionalCastExpr *CXXFExpr =
- dyn_cast<CXXFunctionalCastExpr>(E))
- return LValue::MakeAddr(
- EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
- assert(isa<CStyleCastExpr>(E) &&
- "EmitCastLValue - Expected CStyleCastExpr");
- return EmitLValue(E->getSubExpr());
- }
-
// If this is an aggregate-to-aggregate cast, just use the input's address as
// the lvalue.
- if (E->getCastKind() == CastExpr::CK_NoOp)
+ if (E->getCastKind() == CastExpr::CK_NoOp ||
+ E->getCastKind() == CastExpr::CK_ConstructorConversion ||
+ E->getCastKind() == CastExpr::CK_UserDefinedConversion)
return EmitLValue(E->getSubExpr());
// If this is an lvalue cast, treat it as a no-op.
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed Sep 9 16:33:21 2009
@@ -184,19 +184,12 @@
LValue::MakeAddr(CastPtr, 0));
return;
}
- if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
- if (const CXXFunctionalCastExpr *CXXFExpr =
- dyn_cast<CXXFunctionalCastExpr>(E))
- CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
- else
- if (isa<CStyleCastExpr>(E))
- Visit(E->getSubExpr());
- return;
- }
// FIXME: Remove the CK_Unknown check here.
assert((E->getCastKind() == CastExpr::CK_NoOp ||
- E->getCastKind() == CastExpr::CK_Unknown) &&
+ E->getCastKind() == CastExpr::CK_Unknown ||
+ E->getCastKind() == CastExpr::CK_UserDefinedConversion ||
+ E->getCastKind() == CastExpr::CK_ConstructorConversion) &&
"Only no-op casts allowed!");
assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
E->getType()) &&
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Sep 9 16:33:21 2009
@@ -227,14 +227,6 @@
return llvm::Constant::getNullValue(ConvertType(E->getType()));
}
Value *VisitCastExpr(const CastExpr *E) {
- if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
- if (const CXXFunctionalCastExpr *CXXFExpr =
- dyn_cast<CXXFunctionalCastExpr>(E))
- return CGF.EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal();
- assert(isa<CStyleCastExpr>(E) &&
- "VisitCastExpr - missing CStyleCastExpr");
- }
-
// Make sure to evaluate VLA bounds now so that we have them for later.
if (E->getType()->isVariablyModifiedType())
CGF.EmitVLASize(E->getType());
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Sep 9 16:33:21 2009
@@ -324,17 +324,6 @@
llvm::BasicBlock *FalseBlock) {
if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
- if (const CastExpr *E = dyn_cast<CastExpr>(Cond))
- if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
- if (const CXXFunctionalCastExpr *CXXFExpr =
- dyn_cast<CXXFunctionalCastExpr>(E)) {
- EmitCXXFunctionalCastExpr(CXXFExpr);
- return;
- }
- else if (isa<CStyleCastExpr>(E))
- return EmitBranchOnBoolExpr(E->getSubExpr(), TrueBlock, FalseBlock);
- assert(false && "EmitBranchOnBoolExpr - Expected CStyleCastExpr");
- }
if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
// Handle X && Y in a condition.
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Sep 9 16:33:21 2009
@@ -841,8 +841,6 @@
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
const CXXMethodDecl *MD);
- RValue EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E);
-
RValue EmitBuiltinExpr(const FunctionDecl *FD,
unsigned BuiltinID, const CallExpr *E);
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Sep 9 16:33:21 2009
@@ -1834,6 +1834,12 @@
MultiExprArg Args,
SourceLocation rParenLoc);
+ OwningExprResult BuildCXXCastArgument(SourceLocation CastLoc,
+ QualType Ty,
+ CastExpr::CastKind Kind,
+ CXXMethodDecl *Method,
+ ExprArg Arg);
+
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Wed Sep 9 16:33:21 2009
@@ -44,7 +44,8 @@
const SourceRange &DestRange);
static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
- CastExpr::CastKind &Kind);
+ CastExpr::CastKind &Kind,
+ CXXMethodDecl *&ConversionDecl);
static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
const SourceRange &DestRange,
@@ -143,8 +144,22 @@
case tok::kw_static_cast: {
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- if (!TypeDependent)
- CheckStaticCast(*this, Ex, DestType, OpRange, Kind);
+ if (!TypeDependent) {
+ CXXMethodDecl *Method = 0;
+
+ CheckStaticCast(*this, Ex, DestType, OpRange, Kind, Method);
+
+ if (Method) {
+ OwningExprResult CastArg
+ = BuildCXXCastArgument(OpLoc, DestType.getNonReferenceType(),
+ Kind, Method, Owned(Ex));
+ if (CastArg.isInvalid())
+ return ExprError();
+
+ Ex = CastArg.takeAs<Expr>();
+ }
+ }
+
return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
Kind, Ex, DestType, OpLoc));
}
@@ -359,7 +374,8 @@
/// implicit conversions explicit and getting rid of data loss warnings.
void
CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
- const SourceRange &OpRange, CastExpr::CastKind &Kind) {
+ const SourceRange &OpRange, CastExpr::CastKind &Kind,
+ CXXMethodDecl *&ConversionDecl) {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
@@ -371,7 +387,6 @@
Self.DefaultFunctionArrayConversion(SrcExpr);
unsigned msg = diag::err_bad_cxx_cast_generic;
- CXXMethodDecl *ConversionDecl = 0;
if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind,
OpRange, msg, ConversionDecl)
!= TC_Success && msg != 0)
@@ -421,9 +436,16 @@
// [...] if the declaration "T t(e);" is well-formed, [...].
tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg,
ConversionDecl);
- if (tcr != TC_NotApplicable)
+ if (tcr != TC_NotApplicable) {
+ if (ConversionDecl) {
+ if (isa<CXXConstructorDecl>(ConversionDecl))
+ Kind = CastExpr::CK_ConstructorConversion;
+ else if (isa<CXXConversionDecl>(ConversionDecl))
+ Kind = CastExpr::CK_UserDefinedConversion;
+ }
return tcr;
-
+ }
+
// C++ 5.2.9p6: May apply the reverse of any standard conversion, except
// lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean
// conversions, subject to further restrictions.
@@ -787,10 +809,12 @@
/*ForceRValue=*/false,
/*InOverloadResolution=*/false);
- if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion)
+ if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) {
if (CXXMethodDecl *MD =
dyn_cast<CXXMethodDecl>(ICS.UserDefined.ConversionFunction))
ConversionDecl = MD;
+ }
+
return ICS.ConversionKind == ImplicitConversionSequence::BadConversion ?
TC_NotApplicable : TC_Success;
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Sep 9 16:33:21 2009
@@ -3171,25 +3171,23 @@
// If the Expr being casted is a ParenListExpr, handle it specially.
if (isa<ParenListExpr>(castExpr))
return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),castType);
- CXXMethodDecl *ConversionDecl = 0;
+ CXXMethodDecl *Method = 0;
if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr,
- Kind, ConversionDecl))
+ Kind, Method))
return ExprError();
- if (ConversionDecl) {
- // encounterred a c-style cast requiring a conversion function.
- if (CXXConversionDecl *CD = dyn_cast<CXXConversionDecl>(ConversionDecl)) {
- castExpr =
- new (Context) CXXFunctionalCastExpr(castType.getNonReferenceType(),
- castType, LParenLoc,
- CastExpr::CK_UserDefinedConversion,
- castExpr, CD,
- RParenLoc);
- Kind = CastExpr::CK_UserDefinedConversion;
- }
- // FIXME. AST for when dealing with conversion functions (FunctionDecl).
+
+ if (Method) {
+ OwningExprResult CastArg = BuildCXXCastArgument(LParenLoc, castType, Kind,
+ Method, move(Op));
+
+ if (CastArg.isInvalid())
+ return ExprError();
+
+ castExpr = CastArg.takeAs<Expr>();
+ } else {
+ Op.release();
}
- Op.release();
return Owned(new (Context) CStyleCastExpr(castType.getNonReferenceType(),
Kind, castExpr, castType,
LParenLoc, RParenLoc));
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81383&r1=81382&r2=81383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Sep 9 16:33:21 2009
@@ -224,19 +224,25 @@
//
if (NumExprs == 1) {
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXMethodDecl *ConversionDecl = 0;
- if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, ConversionDecl,
- /*functional-style*/true))
+ CXXMethodDecl *Method = 0;
+ if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, Method,
+ /*FunctionalStyle=*/true))
return ExprError();
- // We done't build this AST for X(i) where we are constructing an object.
- if (!ConversionDecl || !isa<CXXConstructorDecl>(ConversionDecl)) {
- exprs.release();
- return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
- Ty, TyBeginLoc,
- CastExpr::CK_UserDefinedConversion,
- Exprs[0], ConversionDecl,
- RParenLoc));
+
+ exprs.release();
+ if (Method) {
+ OwningExprResult CastArg
+ = BuildCXXCastArgument(TypeRange.getBegin(), Ty.getNonReferenceType(),
+ Kind, Method, Owned(Exprs[0]));
+ if (CastArg.isInvalid())
+ return ExprError();
+
+ Exprs[0] = CastArg.takeAs<Expr>();
}
+
+ return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+ Ty, TyBeginLoc, Kind,
+ Exprs[0], RParenLoc));
}
if (const RecordType *RT = Ty->getAs<RecordType>()) {
@@ -919,30 +925,25 @@
{
FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
- if (CXXConversionDecl *CV = dyn_cast<CXXConversionDecl>(FD)) {
- // FIXME. Get actual Source Location.
- From =
- new (Context) CXXFunctionalCastExpr(ToType.getNonReferenceType(),
- ToType, SourceLocation(),
- CastExpr::CK_UserDefinedConversion,
- From, CV,
- SourceLocation());
+ if (isa<CXXConversionDecl>(FD))
CastKind = CastExpr::CK_UserDefinedConversion;
- }
- else if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
- // FIXME. Do we need to check for isLValueReferenceType?
- DefaultFunctionArrayConversion(From);
- OwningExprResult InitResult =
- BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
- ToType.getNonReferenceType(), CD,
- MultiExprArg(*this, (void**)&From, 1));
- // Take ownership of this expression.
- From = InitResult.takeAs<Expr>();
- CastKind = CastExpr::CK_ConstructorConversion ;
- }
- ImpCastExprToType(From, ToType.getNonReferenceType(),
- CastKind,
- ToType->isLValueReferenceType());
+ else if (isa<CXXConstructorDecl>(FD))
+ CastKind = CastExpr::CK_ConstructorConversion;
+ else
+ assert(0 && "Unknown conversion function kind!");
+
+ OwningExprResult CastArg
+ = BuildCXXCastArgument(From->getLocStart(),
+ ToType.getNonReferenceType(),
+ CastKind, cast<CXXMethodDecl>(FD),
+ Owned(From));
+
+ if (CastArg.isInvalid())
+ return true;
+
+ From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
+ CastKind, CastArg.takeAs<Expr>(),
+ ToType->isLValueReferenceType());
return false;
}
@@ -1889,6 +1890,42 @@
ConvName, DeclPtrTy(), SS);
}
+Sema::OwningExprResult Sema::BuildCXXCastArgument(SourceLocation CastLoc,
+ QualType Ty,
+ CastExpr::CastKind Kind,
+ CXXMethodDecl *Method,
+ ExprArg Arg) {
+ Expr *From = Arg.takeAs<Expr>();
+
+ switch (Kind) {
+ default: assert(0 && "Unhandled cast kind!");
+ case CastExpr::CK_ConstructorConversion: {
+ DefaultFunctionArrayConversion(From);
+
+ return BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
+ MultiExprArg(*this, (void **)&From, 1));
+ }
+
+ case CastExpr::CK_UserDefinedConversion: {
+ // Create an implicit member expr to refer to the conversion operator.
+ MemberExpr *ME =
+ new (Context) MemberExpr(From, From->getType()->isPointerType(), Method,
+ SourceLocation(), Method->getType());
+
+
+ // And an implicit call expr that calls it.
+ QualType ResultType = Method->getResultType().getNonReferenceType();
+ CXXMemberCallExpr *CE =
+ new (Context) CXXMemberCallExpr(Context, ME, 0, 0,
+ ResultType,
+ SourceLocation());
+
+ return Owned(CE);
+ }
+
+ }
+}
+
Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
Expr *FullExpr = Arg.takeAs<Expr>();
if (FullExpr)
More information about the cfe-commits
mailing list