[cfe-commits] r72144 - in /cfe/trunk: lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp test/SemaTemplate/instantiate-expr-3.cpp

Douglas Gregor dgregor at apple.com
Tue May 19 16:10:32 PDT 2009


Author: dgregor
Date: Tue May 19 18:10:31 2009
New Revision: 72144

URL: http://llvm.org/viewvc/llvm-project?rev=72144&view=rev
Log:
Template instantiation for __builtin_va_arg.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
    cfe/trunk/test/SemaTemplate/instantiate-expr-3.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=72144&r1=72143&r2=72144&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue May 19 18:10:31 2009
@@ -5253,11 +5253,13 @@
   } else {
     // Otherwise, the va_list argument must be an l-value because
     // it is modified by va_arg.
-    if (CheckForModifiableLvalue(E, BuiltinLoc, *this))
+    if (!E->isTypeDependent() && 
+        CheckForModifiableLvalue(E, BuiltinLoc, *this))
       return ExprError();
   }
 
-  if (!Context.hasSameType(VaListType, E->getType())) {
+  if (!E->isTypeDependent() &&
+      !Context.hasSameType(VaListType, E->getType())) {
     return ExprError(Diag(E->getLocStart(),
                          diag::err_first_argument_to_va_arg_not_of_type_va_list)
       << OrigExpr->getType() << E->getSourceRange());

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=72144&r1=72143&r2=72144&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Tue May 19 18:10:31 2009
@@ -59,6 +59,7 @@
     OwningExprResult VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
     OwningExprResult VisitShuffleVectorExpr(ShuffleVectorExpr *E);
     OwningExprResult VisitChooseExpr(ChooseExpr *E);
+    OwningExprResult VisitVAArgExpr(VAArgExpr *E);
     OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
     OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
     OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
@@ -162,12 +163,17 @@
                                                  *Arg.getAsIntegral(),
                                                  T, 
                                        E->getSourceRange().getBegin()));
-  } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))
+  } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
     NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Parm);
-  else if (isa<FunctionDecl>(D) || isa<OverloadedFunctionDecl>(D))
+  } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    if (Var->hasLocalStorage())
+      NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Var);
+    else
+      assert(false && "Cannot instantiation non-local variable declarations");
+  } else if (isa<FunctionDecl>(D) || isa<OverloadedFunctionDecl>(D)) {
     // FIXME: Instantiate decl!
     NewD = cast<ValueDecl>(D);
-  else
+  } else
     assert(false && "Unhandled declaratrion reference kind");
 
   if (!NewD)
@@ -540,6 +546,24 @@
                                  E->getRParenLoc());
 }
 
+Sema::OwningExprResult TemplateExprInstantiator::VisitVAArgExpr(VAArgExpr *E) {
+  OwningExprResult SubExpr = Visit(E->getSubExpr());
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  SourceLocation FakeTypeLoc 
+    = SemaRef.PP.getLocForEndOfToken(E->getSubExpr()->getSourceRange()
+                                       .getEnd());
+  QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
+                                       /*FIXME:*/FakeTypeLoc, 
+                                       DeclarationName());
+  if (T.isNull())
+    return SemaRef.ExprError();
+
+  return SemaRef.ActOnVAArg(E->getBuiltinLoc(), move(SubExpr),
+                            T.getAsOpaquePtr(), E->getRParenLoc());
+}
+
 Sema::OwningExprResult 
 TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
   bool isSizeOf = E->isSizeOf();

Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-3.cpp?rev=72144&r1=72143&r2=72144&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-3.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-3.cpp Tue May 19 18:10:31 2009
@@ -100,3 +100,19 @@
 template struct Choose0<true, int, float, int&>;
 template struct Choose0<false, int, float, float&>;
 template struct Choose0<true, int, float, float&>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// va_arg
+// ---------------------------------------------------------------------
+template<typename ArgType>
+struct VaArg0 {
+  void f(int n, ...) {
+    __builtin_va_list va;
+    __builtin_va_start(va, n);
+    for (int i = 0; i != n; ++i)
+      (void)__builtin_va_arg(va, ArgType);
+    __builtin_va_end(va);
+  }
+};
+
+template struct VaArg0<int>;





More information about the cfe-commits mailing list