[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