[cfe-commits] r43006 - in /cfe/trunk: AST/Expr.cpp AST/StmtPrinter.cpp CodeGen/CGExprScalar.cpp Parse/ParseExpr.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/AST/Expr.h include/clang/AST/StmtNodes.def include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h
Anders Carlsson
andersca at mac.com
Mon Oct 15 13:28:49 PDT 2007
Author: andersca
Date: Mon Oct 15 15:28:48 2007
New Revision: 43006
URL: http://llvm.org/viewvc/llvm-project?rev=43006&view=rev
Log:
Add code generation and sema checking for __builtin_va_arg.
Modified:
cfe/trunk/AST/Expr.cpp
cfe/trunk/AST/StmtPrinter.cpp
cfe/trunk/CodeGen/CGExprScalar.cpp
cfe/trunk/Parse/ParseExpr.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/StmtNodes.def
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Action.h
Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Mon Oct 15 15:28:48 2007
@@ -1054,6 +1054,15 @@
return reinterpret_cast<Stmt**>(&SubExprs)+END_EXPR;
}
+// VAArgExpr
+Stmt::child_iterator VAArgExpr::child_begin() {
+ return reinterpret_cast<Stmt**>(&Val);
+}
+
+Stmt::child_iterator VAArgExpr::child_end() {
+ return reinterpret_cast<Stmt**>(&Val)+1;
+}
+
// InitListExpr
Stmt::child_iterator InitListExpr::child_begin() {
return reinterpret_cast<Stmt**>(&InitExprs[0]);
Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Mon Oct 15 15:28:48 2007
@@ -587,6 +587,14 @@
OS << " }";
}
+void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
+ OS << "va_arg(";
+ PrintExpr(Node->getSubExpr());
+ OS << ", ";
+ OS << Node->getType().getAsString();
+ OS << ")";
+}
+
// C++
void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
Modified: cfe/trunk/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprScalar.cpp?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/CodeGen/CGExprScalar.cpp Mon Oct 15 15:28:48 2007
@@ -16,6 +16,7 @@
#include "clang/AST/AST.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
+#include "llvm/Intrinsics.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace CodeGen;
@@ -241,6 +242,7 @@
// Other Operators.
Value *VisitConditionalOperator(const ConditionalOperator *CO);
Value *VisitChooseExpr(ChooseExpr *CE);
+ Value *VisitVAArgExpr(VAArgExpr *VE);
Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
return CGF.EmitObjCStringLiteral(E);
}
@@ -892,6 +894,14 @@
return Visit(CondVal != 0 ? E->getLHS() : E->getRHS());
}
+Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE)
+{
+ llvm::Value *ArgValue = EmitLValue(VE->getSubExpr()).getAddress();
+
+ llvm::Value *V = Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));
+ return V;
+}
+
//===----------------------------------------------------------------------===//
// Entry Point into this File
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseExpr.cpp?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/Parse/ParseExpr.cpp Mon Oct 15 15:28:48 2007
@@ -793,9 +793,9 @@
switch (T) {
default: assert(0 && "Not a builtin primary expression!");
- case tok::kw___builtin_va_arg:
- Res = ParseAssignmentExpression();
- if (Res.isInvalid) {
+ case tok::kw___builtin_va_arg: {
+ ExprResult Expr = ParseAssignmentExpression();
+ if (Expr.isInvalid) {
SkipUntil(tok::r_paren);
return Res;
}
@@ -803,11 +803,15 @@
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
return ExprResult(true);
- ParseTypeName();
+ TypeTy *Ty = ParseTypeName();
- MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ if (Tok.isNot(tok::r_paren)) {
+ Diag(Tok, diag::err_expected_rparen);
+ return ExprResult(true);
+ }
+ Res = Actions.ActOnVAArg(StartLoc, Expr.Val, Ty, ConsumeParen());
break;
-
+ }
case tok::kw___builtin_offsetof: {
SourceLocation TypeLoc = Tok.getLocation();
TypeTy *Ty = ParseTypeName();
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Mon Oct 15 15:28:48 2007
@@ -418,6 +418,11 @@
ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
SourceLocation RPLoc);
+ // __builtin_va_arg(expr, type)
+ virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+ ExprTy *expr, TypeTy *type,
+ SourceLocation RPLoc);
+
/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
SourceLocation LAngleBracketLoc, TypeTy *Ty,
@@ -624,6 +629,8 @@
unsigned NewWidth, bool NewSign,
SourceLocation Loc, unsigned DiagID);
+ void InitBuiltinVaListType();
+
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
private:
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Oct 15 15:28:48 2007
@@ -146,23 +146,29 @@
return 0;
}
+void Sema::InitBuiltinVaListType()
+{
+ if (!Context.getBuiltinVaListType().isNull())
+ return;
+
+ IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
+ ScopedDecl *VaDecl = LookupScopedDecl(VaIdent, Decl::IDNS_Ordinary,
+ SourceLocation(), TUScope);
+ TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
+ Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
+}
+
/// LazilyCreateBuiltin - The specified Builtin-ID was first used at file scope.
/// lazily create a decl for it.
ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
Scope *S) {
Builtin::ID BID = (Builtin::ID)bid;
- if ((BID == Builtin::BI__builtin_va_start ||
+ if (BID == Builtin::BI__builtin_va_start ||
BID == Builtin::BI__builtin_va_copy ||
- BID == Builtin::BI__builtin_va_end) &&
- Context.getBuiltinVaListType().isNull()) {
- IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
- ScopedDecl *VaDecl = LookupScopedDecl(VaIdent, Decl::IDNS_Ordinary,
- SourceLocation(), TUScope);
- TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
- Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
- }
-
+ BID == Builtin::BI__builtin_va_end)
+ InitBuiltinVaListType();
+
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R,
FunctionDecl::Extern, false, 0);
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Mon Oct 15 15:28:48 2007
@@ -1859,6 +1859,30 @@
return new ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, RPLoc);
}
+Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
+ ExprTy *expr, TypeTy *type,
+ SourceLocation RPLoc)
+{
+ Expr *E = static_cast<Expr*>(expr);
+ QualType T = QualType::getFromOpaquePtr(type);
+
+ InitBuiltinVaListType();
+
+ Sema::AssignmentCheckResult result;
+
+ result = CheckAssignmentConstraints(Context.getBuiltinVaListType(),
+ E->getType());
+ if (result != Compatible)
+ return Diag(E->getLocStart(),
+ diag::err_first_argument_to_va_arg_not_of_type_va_list,
+ E->getType().getAsString(),
+ E->getSourceRange());
+
+ // FIXME: Warn if a non-POD type is passed in.
+
+ return new VAArgExpr(BuiltinLoc, E, T, RPLoc);
+}
+
// TODO: Move this to SemaObjC.cpp
Sema::ExprResult Sema::ParseObjCStringLiteral(ExprTy *string) {
StringLiteral* S = static_cast<StringLiteral *>(string);
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Oct 15 15:28:48 2007
@@ -976,6 +976,32 @@
virtual child_iterator child_end();
};
+/// VAArgExpr, used for the builtin function __builtin_va_start.
+class VAArgExpr : public Expr {
+ Expr *Val;
+ SourceLocation BuiltinLoc, RParenLoc;
+public:
+ VAArgExpr(SourceLocation BLoc, Expr* e, QualType t, SourceLocation RPLoc)
+ : Expr(VAArgExprClass, t),
+ Val(e),
+ BuiltinLoc(BLoc),
+ RParenLoc(RPLoc) { }
+
+ const Expr *getSubExpr() const { return Val; }
+ Expr *getSubExpr() { return Val; }
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(BuiltinLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == VAArgExprClass;
+ }
+ static bool classof(const VAArgExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
/// InitListExpr, used for struct and array initializers.
class InitListExpr : public Expr {
Expr **InitExprs;
Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Mon Oct 15 15:28:48 2007
@@ -66,6 +66,7 @@
STMT(50, CompoundLiteralExpr , Expr)
STMT(51, OCUVectorElementExpr , Expr)
STMT(52, InitListExpr , Expr)
+STMT(53, VAArgExpr , Expr)
// GNU Extensions.
STMT(55, AddrLabelExpr , Expr)
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Mon Oct 15 15:28:48 2007
@@ -863,7 +863,9 @@
"'va_start' used in function with fixed args")
DIAG(warn_second_parameter_of_va_start_not_last_named_argument, WARNING,
"second parameter of 'va_start' not last named argument")
-
+DIAG(err_first_argument_to_va_arg_not_of_type_va_list, ERROR,
+ "first argument to 'va_arg' is of type '%0' and not 'va_list'")
+
DIAG(warn_return_missing_expr, WARNING,
"non-void function '%0' should return a value")
DIAG(ext_return_missing_expr, EXTENSION,
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43006&r1=43005&r2=43006&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Oct 15 15:28:48 2007
@@ -425,6 +425,13 @@
return 0;
}
+ // __builtin_va_arg(expr, type)
+ virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
+ ExprTy *expr, TypeTy *type,
+ SourceLocation RPLoc) {
+ return 0;
+ }
+
//===------------------------- C++ Expressions --------------------------===//
/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
More information about the cfe-commits
mailing list