[cfe-commits] r66796 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/instantiate-expr-1.cpp

Douglas Gregor dgregor at apple.com
Thu Mar 12 09:53:44 PDT 2009


Author: dgregor
Date: Thu Mar 12 11:53:44 2009
New Revision: 66796

URL: http://llvm.org/viewvc/llvm-project?rev=66796&view=rev
Log:
Straw man for instantiation of expressions. Use it to instantiate the
width of bitfields. 

I'll be burning this down and replacing it with a properly-dispatched
implementation like the one used for types.

Added:
    cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp   (with props)
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=66796&r1=66795&r2=66796&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Mar 12 11:53:44 2009
@@ -1805,6 +1805,11 @@
   QualType InstantiateType(QualType T, const TemplateArgument *TemplateArgs,
                            unsigned NumTemplateArgs,
                            SourceLocation Loc, DeclarationName Entity);
+
+  OwningExprResult InstantiateExpr(Expr *E, 
+                                   const TemplateArgument *TemplateArgs,
+                                   unsigned NumTemplateArgs);
+
   bool 
   InstantiateBaseSpecifiers(ClassTemplateSpecializationDecl *ClassTemplateSpec,
                             ClassTemplateDecl *ClassTemplate);
@@ -2305,7 +2310,7 @@
 template <typename T>
 class ExprOwningPtr : public Action::ExprArg {
 public:
-  ExprOwningPtr(Sema *S, T *expr) : Action::ExprArg(*S, expr) {};
+  ExprOwningPtr(Sema *S, T *expr) : Action::ExprArg(*S, expr) {}
   
   void reset(T* p) { Action::ExprArg::operator=(p); }
   T* get() const { return static_cast<T*>(Action::ExprArg::get()); }

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Mar 12 11:53:44 2009
@@ -550,6 +550,50 @@
   return Instantiator(T);
 }
 
+//===----------------------------------------------------------------------===/
+// Template Instantiation for Expressions
+//===----------------------------------------------------------------------===/
+Sema::OwningExprResult 
+Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
+                      unsigned NumTemplateArgs) {
+  if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
+    return Owned(new (Context) IntegerLiteral(IL->getValue(), IL->getType(),
+                                              IL->getSourceRange().getBegin()));
+  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    Decl *D = DRE->getDecl();
+    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+      assert(NTTP->getDepth() == 0 && "No nested templates yet");
+      QualType T = NTTP->getType();
+      if (T->isDependentType()) {
+        // FIXME: We'll be doing this instantiation a lot. Should we
+        // cache this information in the TemplateArgument itself?
+        T = InstantiateType(T, TemplateArgs, NumTemplateArgs,
+                            E->getSourceRange().getBegin(),
+                            NTTP->getDeclName());
+        if (T.isNull())
+          return ExprError();
+      }
+      return Owned(new (Context) IntegerLiteral(
+                            *TemplateArgs[NTTP->getPosition()].getAsIntegral(),
+                            T, E->getSourceRange().getBegin()));
+    } else
+      assert(false && "Yes, this is lame");
+  } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+    OwningExprResult SubExpr
+      = InstantiateExpr(PE->getSubExpr(), TemplateArgs,
+                        NumTemplateArgs);
+    if (SubExpr.isInvalid())
+      return ExprError();
+
+    return Owned(new (Context) ParenExpr(E->getSourceRange().getBegin(),
+                                         E->getSourceRange().getEnd(),
+                                         (Expr *)SubExpr.release()));
+  } else 
+    assert(false && "Yes, this is lame");
+
+  return ExprError();
+}
+
 /// \brief Instantiate the base class specifiers of the given class
 /// template specialization.
 ///
@@ -694,6 +738,7 @@
     else if (FieldDecl *Field = dyn_cast<FieldDecl>(*Member)) {
       // FIXME: Simplified instantiation of fields needs to be made
       // "real".
+      bool InvalidDecl = false;
       QualType T = Field->getType();
       if (T->isDependentType())  {
         T = InstantiateType(T, ClassTemplateSpec->getTemplateArgs(),
@@ -710,20 +755,40 @@
           Diag(Field->getLocation(), diag::err_field_instantiates_to_function) 
             << T;
           T = QualType();
+          InvalidDecl = true;
         }
       }
 
+      Expr *BitWidth = Field->getBitWidth();
+      if (InvalidDecl)
+        BitWidth = 0;
+      if (BitWidth && 
+          (BitWidth->isTypeDependent() || BitWidth->isValueDependent())) {
+        OwningExprResult InstantiatedBitWidth
+          = InstantiateExpr(BitWidth, 
+                            ClassTemplateSpec->getTemplateArgs(),
+                            ClassTemplateSpec->getNumTemplateArgs());
+        if (InstantiatedBitWidth.isInvalid()) {
+          Invalid = InvalidDecl = true;
+          BitWidth = 0;
+        } else
+          BitWidth = (Expr *)InstantiatedBitWidth.release();
+      }
+
       FieldDecl *New = CheckFieldDecl(Field->getDeclName(), T,
                                       ClassTemplateSpec, 
                                       Field->getLocation(),
                                       Field->isMutable(),
-                                      Field->getBitWidth(),
+                                      BitWidth,
                                       Field->getAccess(),
                                       0);
       if (New) {
         ClassTemplateSpec->addDecl(New);
         Fields.push_back(New);
 
+        if (InvalidDecl)
+          New->setInvalidDecl();
+
         if (New->isInvalidDecl())
           Invalid = true;
       }

Added: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp?rev=66796&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp Thu Mar 12 11:53:44 2009
@@ -0,0 +1,12 @@
+// RUN: clang -fsyntax-only -verify %s
+
+template<int I, int J>
+struct Bitfields {
+  int simple : I; // expected-error{{bit-field 'simple' has zero width}}
+  int parens : (J);
+};
+
+void test_Bitfields(Bitfields<0, 5> *b) {
+  (void)sizeof(Bitfields<10, 5>);
+  (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'struct Bitfields<0, 1>' requested here}}
+}

Propchange: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp

------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list