forked from OSchip/llvm-project
parent
443e040d06
commit
d7cfc246f6
|
@ -1551,98 +1551,6 @@ public:
|
|||
static GNUNullExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
||||
};
|
||||
|
||||
/// OverloadExpr - Clang builtin function __builtin_overload.
|
||||
/// This AST node provides a way to overload functions in C.
|
||||
///
|
||||
/// The first argument is required to be a constant expression, for the number
|
||||
/// of arguments passed to each candidate function.
|
||||
///
|
||||
/// The next N arguments, where N is the value of the constant expression,
|
||||
/// are the values to be passed as arguments.
|
||||
///
|
||||
/// The rest of the arguments are values of pointer to function type, which
|
||||
/// are the candidate functions for overloading.
|
||||
///
|
||||
/// The result is a equivalent to a CallExpr taking N arguments to the
|
||||
/// candidate function whose parameter types match the types of the N arguments.
|
||||
///
|
||||
/// example: float Z = __builtin_overload(2, X, Y, modf, mod, modl);
|
||||
/// If X and Y are long doubles, Z will assigned the result of modl(X, Y);
|
||||
/// If X and Y are floats, Z will be assigned the result of modf(X, Y);
|
||||
class OverloadExpr : public Expr {
|
||||
// SubExprs - the list of values passed to the __builtin_overload function.
|
||||
// SubExpr[0] is a constant expression
|
||||
// SubExpr[1-N] are the parameters to pass to the matching function call
|
||||
// SubExpr[N-...] are the candidate functions, of type pointer to function.
|
||||
Stmt **SubExprs;
|
||||
|
||||
// NumExprs - the size of the SubExprs array
|
||||
unsigned NumExprs;
|
||||
|
||||
// The index of the matching candidate function
|
||||
unsigned FnIndex;
|
||||
|
||||
SourceLocation BuiltinLoc;
|
||||
SourceLocation RParenLoc;
|
||||
public:
|
||||
OverloadExpr(ASTContext& C, Expr **args, unsigned nexprs, unsigned idx,
|
||||
QualType t, SourceLocation bloc, SourceLocation rploc)
|
||||
: Expr(OverloadExprClass, t), NumExprs(nexprs), FnIndex(idx),
|
||||
BuiltinLoc(bloc), RParenLoc(rploc) {
|
||||
SubExprs = new (C) Stmt*[nexprs];
|
||||
for (unsigned i = 0; i != nexprs; ++i)
|
||||
SubExprs[i] = args[i];
|
||||
}
|
||||
|
||||
~OverloadExpr() {}
|
||||
|
||||
void Destroy(ASTContext& C);
|
||||
|
||||
/// arg_begin - Return a pointer to the list of arguments that will be passed
|
||||
/// to the matching candidate function, skipping over the initial constant
|
||||
/// expression.
|
||||
typedef ConstExprIterator const_arg_iterator;
|
||||
const_arg_iterator arg_begin() const { return &SubExprs[0]+1; }
|
||||
const_arg_iterator arg_end(ASTContext& Ctx) const {
|
||||
return &SubExprs[0]+1+getNumArgs(Ctx);
|
||||
}
|
||||
|
||||
/// getNumArgs - Return the number of arguments to pass to the candidate
|
||||
/// functions.
|
||||
unsigned getNumArgs(ASTContext &Ctx) const {
|
||||
return getExpr(0)->getIntegerConstantExprValue(Ctx).getZExtValue();
|
||||
}
|
||||
|
||||
/// getNumSubExprs - Return the size of the SubExprs array. This includes the
|
||||
/// constant expression, the actual arguments passed in, and the function
|
||||
/// pointers.
|
||||
unsigned getNumSubExprs() const { return NumExprs; }
|
||||
|
||||
/// getExpr - Return the Expr at the specified index.
|
||||
Expr *getExpr(unsigned Index) const {
|
||||
assert((Index < NumExprs) && "Arg access out of range!");
|
||||
return cast<Expr>(SubExprs[Index]);
|
||||
}
|
||||
|
||||
/// getFn - Return the matching candidate function for this OverloadExpr.
|
||||
Expr *getFn() const { return cast<Expr>(SubExprs[FnIndex]); }
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
return SourceRange(BuiltinLoc, RParenLoc);
|
||||
}
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OverloadExprClass;
|
||||
}
|
||||
static bool classof(const OverloadExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
virtual child_iterator child_begin();
|
||||
virtual child_iterator child_end();
|
||||
|
||||
virtual void EmitImpl(llvm::Serializer& S) const;
|
||||
static OverloadExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
||||
};
|
||||
|
||||
/// VAArgExpr, used for the builtin function __builtin_va_start.
|
||||
class VAArgExpr : public Expr {
|
||||
Stmt *Val;
|
||||
|
|
|
@ -131,7 +131,6 @@ STMT(ObjCKVCRefExpr , Expr)
|
|||
STMT(ObjCSuperExpr , Expr)
|
||||
|
||||
// Clang Extensions.
|
||||
STMT(OverloadExpr , Expr)
|
||||
STMT(ShuffleVectorExpr , Expr)
|
||||
STMT(BlockExpr , Expr)
|
||||
STMT(BlockDeclRefExpr , Expr)
|
||||
|
|
|
@ -294,7 +294,6 @@ KEYWORD(__null , NOTC90|NOTC99|EXTCPP|EXTCPP0x) // C++-only
|
|||
KEYWORD(__alignof , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
KEYWORD(__attribute , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
KEYWORD(__builtin_choose_expr , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
KEYWORD(__builtin_overload , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
KEYWORD(__builtin_offsetof , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
KEYWORD(__builtin_types_compatible_p, EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
KEYWORD(__builtin_va_arg , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
|
||||
|
|
|
@ -748,14 +748,6 @@ public:
|
|||
SourceLocation RPLoc) {
|
||||
return 0;
|
||||
}
|
||||
// __builtin_overload(...)
|
||||
virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
|
||||
SourceLocation *CommaLocs,
|
||||
SourceLocation BuiltinLoc,
|
||||
SourceLocation RPLoc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// __builtin_va_arg(expr, type)
|
||||
virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
|
||||
|
|
|
@ -583,7 +583,6 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
|
|||
// An assignment expression [...] is not an lvalue.
|
||||
return LV_InvalidExpression;
|
||||
}
|
||||
// FIXME: OverloadExprClass
|
||||
case CallExprClass:
|
||||
case CXXOperatorCallExprClass:
|
||||
case CXXMemberCallExprClass: {
|
||||
|
@ -1487,13 +1486,6 @@ void SizeOfAlignOfExpr::Destroy(ASTContext& C) {
|
|||
Expr::Destroy(C);
|
||||
}
|
||||
|
||||
void OverloadExpr::Destroy(ASTContext& C) {
|
||||
DestroyChildren(C);
|
||||
C.Deallocate(SubExprs);
|
||||
this->~OverloadExpr();
|
||||
C.Deallocate(this);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DesignatedInitExpr
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1757,10 +1749,6 @@ Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; }
|
|||
Stmt::child_iterator GNUNullExpr::child_begin() { return child_iterator(); }
|
||||
Stmt::child_iterator GNUNullExpr::child_end() { return child_iterator(); }
|
||||
|
||||
// OverloadExpr
|
||||
Stmt::child_iterator OverloadExpr::child_begin() { return &SubExprs[0]; }
|
||||
Stmt::child_iterator OverloadExpr::child_end() { return &SubExprs[0]+NumExprs; }
|
||||
|
||||
// ShuffleVectorExpr
|
||||
Stmt::child_iterator ShuffleVectorExpr::child_begin() {
|
||||
return &SubExprs[0];
|
||||
|
|
|
@ -866,15 +866,6 @@ void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
|
|||
OS << "__null";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
|
||||
OS << "__builtin_overload(";
|
||||
for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
|
||||
if (i) OS << ", ";
|
||||
PrintExpr(Node->getExpr(i));
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
|
||||
OS << "__builtin_shufflevector(";
|
||||
for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
|
||||
|
|
|
@ -917,27 +917,6 @@ GNUNullExpr *GNUNullExpr::CreateImpl(llvm::Deserializer &D, ASTContext &C) {
|
|||
return new GNUNullExpr(T, TL);
|
||||
}
|
||||
|
||||
void OverloadExpr::EmitImpl(llvm::Serializer& S) const {
|
||||
S.Emit(getType());
|
||||
S.Emit(BuiltinLoc);
|
||||
S.Emit(RParenLoc);
|
||||
S.EmitInt(FnIndex);
|
||||
S.EmitInt(NumExprs);
|
||||
S.BatchEmitOwnedPtrs(NumExprs, &SubExprs[0]);
|
||||
}
|
||||
|
||||
OverloadExpr* OverloadExpr::CreateImpl(llvm::Deserializer& D, ASTContext& C) {
|
||||
QualType T = QualType::ReadVal(D);
|
||||
SourceLocation BL = SourceLocation::ReadVal(D);
|
||||
SourceLocation RP = SourceLocation::ReadVal(D);
|
||||
unsigned FnIndex = D.ReadInt();
|
||||
unsigned NumExprs = D.ReadInt();
|
||||
// FIXME: Avoid extra allocation.
|
||||
llvm::SmallVector<Expr*, 4> Exprs(NumExprs);
|
||||
D.BatchReadOwnedPtrs(NumExprs, Exprs.begin(), C);
|
||||
return new OverloadExpr(C, Exprs.begin(), NumExprs, FnIndex, T, BL, RP);
|
||||
}
|
||||
|
||||
void VAArgExpr::EmitImpl(llvm::Serializer& S) const {
|
||||
S.Emit(getType());
|
||||
S.Emit(BuiltinLoc);
|
||||
|
|
|
@ -81,7 +81,6 @@ public:
|
|||
void VisitStmtExpr(const StmtExpr *E);
|
||||
void VisitBinaryOperator(const BinaryOperator *BO);
|
||||
void VisitBinAssign(const BinaryOperator *E);
|
||||
void VisitOverloadExpr(const OverloadExpr *E);
|
||||
void VisitBinComma(const BinaryOperator *E);
|
||||
|
||||
void VisitObjCMessageExpr(ObjCMessageExpr *E);
|
||||
|
@ -197,20 +196,6 @@ void AggExprEmitter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
|
|||
CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
|
||||
RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
|
||||
E->arg_end(CGF.getContext()));
|
||||
|
||||
assert(RV.isAggregate() && "Return value must be aggregate value!");
|
||||
|
||||
// If the result is ignored, don't copy from the value.
|
||||
if (DestPtr == 0)
|
||||
// FIXME: If the source is volatile, we must read from it.
|
||||
return;
|
||||
|
||||
CGF.EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
|
||||
}
|
||||
|
||||
void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
|
||||
CGF.EmitAnyExpr(E->getLHS());
|
||||
CGF.EmitAggExpr(E->getRHS(), DestPtr, false);
|
||||
|
|
|
@ -94,7 +94,6 @@ public:
|
|||
}
|
||||
ComplexPairTy VisitCallExpr(const CallExpr *E);
|
||||
ComplexPairTy VisitStmtExpr(const StmtExpr *E);
|
||||
ComplexPairTy VisitOverloadExpr(const OverloadExpr *OE);
|
||||
|
||||
// Operators.
|
||||
ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
|
||||
|
@ -260,11 +259,6 @@ ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
|
|||
return CGF.EmitCallExpr(E).getComplexVal();
|
||||
}
|
||||
|
||||
ComplexPairTy ComplexExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
|
||||
return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
|
||||
E->arg_end(CGF.getContext())).getComplexVal();
|
||||
}
|
||||
|
||||
ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
|
||||
return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
|
||||
}
|
||||
|
|
|
@ -322,7 +322,6 @@ public:
|
|||
Value *VisitBlockExpr(const BlockExpr *BE);
|
||||
Value *VisitConditionalOperator(const ConditionalOperator *CO);
|
||||
Value *VisitChooseExpr(ChooseExpr *CE);
|
||||
Value *VisitOverloadExpr(OverloadExpr *OE);
|
||||
Value *VisitVAArgExpr(VAArgExpr *VE);
|
||||
Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
|
||||
return CGF.EmitObjCStringLiteral(E);
|
||||
|
@ -1335,11 +1334,6 @@ Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
|
|||
Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() : E->getRHS());
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::VisitOverloadExpr(OverloadExpr *E) {
|
||||
return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
|
||||
E->arg_end(CGF.getContext())).getScalarVal();
|
||||
}
|
||||
|
||||
Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
|
||||
llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
|
||||
llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
|
||||
|
|
|
@ -574,7 +574,6 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
case tok::kw___builtin_va_arg:
|
||||
case tok::kw___builtin_offsetof:
|
||||
case tok::kw___builtin_choose_expr:
|
||||
case tok::kw___builtin_overload:
|
||||
case tok::kw___builtin_types_compatible_p:
|
||||
return ParseBuiltinPrimaryExpression();
|
||||
case tok::kw___null:
|
||||
|
@ -905,7 +904,6 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
|
|||
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
|
||||
/// assign-expr ')'
|
||||
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
|
||||
/// [CLANG] '__builtin_overload' '(' expr (',' expr)* ')'
|
||||
///
|
||||
/// [GNU] offsetof-member-designator:
|
||||
/// [GNU] identifier
|
||||
|
@ -1049,38 +1047,6 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
|
|||
Expr2.release(), ConsumeParen());
|
||||
break;
|
||||
}
|
||||
case tok::kw___builtin_overload: {
|
||||
ExprVector ArgExprs(Actions);
|
||||
llvm::SmallVector<SourceLocation, 8> CommaLocs;
|
||||
|
||||
// For each iteration through the loop look for assign-expr followed by a
|
||||
// comma. If there is no comma, break and attempt to match r-paren.
|
||||
if (Tok.isNot(tok::r_paren)) {
|
||||
while (1) {
|
||||
OwningExprResult ArgExpr(ParseAssignmentExpression());
|
||||
if (ArgExpr.isInvalid()) {
|
||||
SkipUntil(tok::r_paren);
|
||||
return ExprError();
|
||||
} else
|
||||
ArgExprs.push_back(ArgExpr.release());
|
||||
|
||||
if (Tok.isNot(tok::comma))
|
||||
break;
|
||||
// Move to the next argument, remember where the comma was.
|
||||
CommaLocs.push_back(ConsumeToken());
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to consume the r-paren
|
||||
if (Tok.isNot(tok::r_paren)) {
|
||||
Diag(Tok, diag::err_expected_rparen);
|
||||
SkipUntil(tok::r_paren);
|
||||
return ExprError();
|
||||
}
|
||||
Res = Actions.ActOnOverloadExpr(ArgExprs.take(), ArgExprs.size(),
|
||||
&CommaLocs[0], StartLoc, ConsumeParen());
|
||||
break;
|
||||
}
|
||||
case tok::kw___builtin_types_compatible_p:
|
||||
TypeResult Ty1 = ParseTypeName();
|
||||
|
||||
|
|
|
@ -1164,12 +1164,6 @@ public:
|
|||
ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
|
||||
SourceLocation RPLoc);
|
||||
|
||||
// __builtin_overload(...)
|
||||
virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
|
||||
SourceLocation *CommaLocs,
|
||||
SourceLocation BuiltinLoc,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
// __builtin_va_arg(expr, type)
|
||||
virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
|
||||
ExprTy *expr, TypeTy *type,
|
||||
|
|
|
@ -4444,101 +4444,6 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body,
|
|||
return new (Context) BlockExpr(BSI->TheDecl, BlockTy);
|
||||
}
|
||||
|
||||
/// ExprsMatchFnType - return true if the Exprs in array Args have
|
||||
/// QualTypes that match the QualTypes of the arguments of the FnType.
|
||||
/// The number of arguments has already been validated to match the number of
|
||||
/// arguments in FnType.
|
||||
static bool ExprsMatchFnType(Expr **Args, const FunctionTypeProto *FnType,
|
||||
ASTContext &Context) {
|
||||
unsigned NumParams = FnType->getNumArgs();
|
||||
for (unsigned i = 0; i != NumParams; ++i) {
|
||||
QualType ExprTy = Context.getCanonicalType(Args[i]->getType());
|
||||
QualType ParmTy = Context.getCanonicalType(FnType->getArgType(i));
|
||||
|
||||
if (ExprTy.getUnqualifiedType() != ParmTy.getUnqualifiedType())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Sema::ExprResult Sema::ActOnOverloadExpr(ExprTy **args, unsigned NumArgs,
|
||||
SourceLocation *CommaLocs,
|
||||
SourceLocation BuiltinLoc,
|
||||
SourceLocation RParenLoc) {
|
||||
// __builtin_overload requires at least 2 arguments
|
||||
if (NumArgs < 2)
|
||||
return Diag(RParenLoc, diag::err_typecheck_call_too_few_args)
|
||||
<< SourceRange(BuiltinLoc, RParenLoc);
|
||||
|
||||
// The first argument is required to be a constant expression. It tells us
|
||||
// the number of arguments to pass to each of the functions to be overloaded.
|
||||
Expr **Args = reinterpret_cast<Expr**>(args);
|
||||
Expr *NParamsExpr = Args[0];
|
||||
llvm::APSInt constEval(32);
|
||||
SourceLocation ExpLoc;
|
||||
if (!NParamsExpr->isIntegerConstantExpr(constEval, Context, &ExpLoc))
|
||||
return Diag(ExpLoc, diag::err_overload_expr_requires_non_zero_constant)
|
||||
<< NParamsExpr->getSourceRange();
|
||||
|
||||
// Verify that the number of parameters is > 0
|
||||
unsigned NumParams = constEval.getZExtValue();
|
||||
if (NumParams == 0)
|
||||
return Diag(ExpLoc, diag::err_overload_expr_requires_non_zero_constant)
|
||||
<< NParamsExpr->getSourceRange();
|
||||
// Verify that we have at least 1 + NumParams arguments to the builtin.
|
||||
if ((NumParams + 1) > NumArgs)
|
||||
return Diag(RParenLoc, diag::err_typecheck_call_too_few_args)
|
||||
<< SourceRange(BuiltinLoc, RParenLoc);
|
||||
|
||||
// Figure out the return type, by matching the args to one of the functions
|
||||
// listed after the parameters.
|
||||
OverloadExpr *OE = 0;
|
||||
for (unsigned i = NumParams + 1; i < NumArgs; ++i) {
|
||||
// UsualUnaryConversions will convert the function DeclRefExpr into a
|
||||
// pointer to function.
|
||||
Expr *Fn = UsualUnaryConversions(Args[i]);
|
||||
const FunctionTypeProto *FnType = 0;
|
||||
if (const PointerType *PT = Fn->getType()->getAsPointerType())
|
||||
FnType = PT->getPointeeType()->getAsFunctionTypeProto();
|
||||
|
||||
// The Expr type must be FunctionTypeProto, since FunctionTypeProto has no
|
||||
// parameters, and the number of parameters must match the value passed to
|
||||
// the builtin.
|
||||
if (!FnType || (FnType->getNumArgs() != NumParams))
|
||||
return Diag(Fn->getExprLoc(), diag::err_overload_incorrect_fntype)
|
||||
<< Fn->getSourceRange();
|
||||
|
||||
// Scan the parameter list for the FunctionType, checking the QualType of
|
||||
// each parameter against the QualTypes of the arguments to the builtin.
|
||||
// If they match, return a new OverloadExpr.
|
||||
if (ExprsMatchFnType(Args+1, FnType, Context)) {
|
||||
if (OE)
|
||||
return Diag(Fn->getExprLoc(), diag::err_overload_multiple_match)
|
||||
<< OE->getFn()->getSourceRange();
|
||||
// Remember our match, and continue processing the remaining arguments
|
||||
// to catch any errors.
|
||||
OE = new (Context) OverloadExpr(Context, Args, NumArgs, i,
|
||||
FnType->getResultType().getNonReferenceType(),
|
||||
BuiltinLoc, RParenLoc);
|
||||
}
|
||||
}
|
||||
// Return the newly created OverloadExpr node, if we succeded in matching
|
||||
// exactly one of the candidate functions.
|
||||
if (OE)
|
||||
return OE;
|
||||
|
||||
// If we didn't find a matching function Expr in the __builtin_overload list
|
||||
// the return an error.
|
||||
std::string typeNames;
|
||||
for (unsigned i = 0; i != NumParams; ++i) {
|
||||
if (i != 0) typeNames += ", ";
|
||||
typeNames += Args[i+1]->getType().getAsString();
|
||||
}
|
||||
|
||||
return Diag(BuiltinLoc, diag::err_overload_no_match)
|
||||
<< typeNames << SourceRange(BuiltinLoc, RParenLoc);
|
||||
}
|
||||
|
||||
Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
|
||||
ExprTy *expr, TypeTy *type,
|
||||
SourceLocation RPLoc) {
|
||||
|
|
Loading…
Reference in New Issue