[cfe-commits] r109967 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-attr.cpp

John McCall rjmccall at apple.com
Sat Jul 31 19:01:53 PDT 2010


Author: rjmccall
Date: Sat Jul 31 21:01:53 2010
New Revision: 109967

URL: http://llvm.org/viewvc/llvm-project?rev=109967&view=rev
Log:
Instantiate attributes from the pattern record when instantiating
a class template.  Fixes rdar://problem/8243419.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/SemaTemplate/instantiate-attr.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=109967&r1=109966&r2=109967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Jul 31 21:01:53 2010
@@ -3905,6 +3905,9 @@
                    TemplateSpecializationKind TSK,
                    bool Complain = true);
 
+  void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+                        Decl *Pattern, Decl *Inst);
+
   bool
   InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
                            ClassTemplateSpecializationDecl *ClassTemplateSpec,

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=109967&r1=109966&r2=109967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Jul 31 21:01:53 2010
@@ -1206,6 +1206,9 @@
   bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
   Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope);
 
+  // Pull attributes from the pattern onto the instantiation.
+  InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
+
   // Start the definition of this instantiation.
   Instantiation->startDefinition();
   

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=109967&r1=109966&r2=109967&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Jul 31 21:01:53 2010
@@ -31,8 +31,6 @@
     DeclContext *Owner;
     const MultiLevelTemplateArgumentList &TemplateArgs;
 
-    void InstantiateAttrs(Decl *Tmpl, Decl *New);
-      
   public:
     typedef Sema::OwningExprResult OwningExprResult;
 
@@ -144,28 +142,29 @@
 }
 
 // FIXME: Is this still too simple?
-void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
+void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+                            Decl *Tmpl, Decl *New) {
   for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
        TmplAttr = TmplAttr->getNext()) {
     // FIXME: This should be generalized to more than just the AlignedAttr.
     if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
       if (Aligned->isDependent()) {
         // The alignment expression is not potentially evaluated.
-        EnterExpressionEvaluationContext Unevaluated(SemaRef,
+        EnterExpressionEvaluationContext Unevaluated(*this,
                                                      Action::Unevaluated);
 
-        OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(),
-                                                    TemplateArgs);
+        OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+                                            TemplateArgs);
         if (!Result.isInvalid())
           // FIXME: Is this the correct source location?
-          SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
-                                 New, Result.takeAs<Expr>());
+          AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
+                         New, Result.takeAs<Expr>());
         continue;
       }
     }
 
     // FIXME: Is cloning correct for all attributes?
-    Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
+    Attr *NewAttr = TmplAttr->clone(Context);
     New->addAttr(NewAttr);
   }
 }
@@ -234,7 +233,7 @@
     Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
   }
 
-  InstantiateAttrs(D, Typedef);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
 
   Typedef->setAccess(D->getAccess());
   Owner->addDecl(Typedef);
@@ -399,7 +398,7 @@
     if (Owner->isFunctionOrMethod())
       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
   }
-  InstantiateAttrs(D, Var);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
   
   // Link instantiations of static data members back to the template from
   // which they were instantiated.
@@ -518,7 +517,7 @@
     return 0;
   }
 
-  InstantiateAttrs(D, Field);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Field);
   
   if (Invalid)
     Field->setInvalidDecl();
@@ -1975,7 +1974,7 @@
                                                  Proto->getExtInfo()));
   }
 
-  InstantiateAttrs(Tmpl, New);
+  SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
 
   return false;
 }

Modified: cfe/trunk/test/SemaTemplate/instantiate-attr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-attr.cpp?rev=109967&r1=109966&r2=109967&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-attr.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-attr.cpp Sat Jul 31 21:01:53 2010
@@ -11,3 +11,16 @@
 int a[sizeof(A<int>) == 16 ? 1 : -1];
 int a2[sizeof(A<int>::B) == 16 ? 1 : -1];
 
+// rdar://problem/8243419
+namespace test1 {
+  template <typename T> struct A {
+    int a;
+    T b[0];
+  } __attribute__((packed));
+
+  typedef A<unsigned long> type;
+
+  int test0[sizeof(type) == 4 ? 1 : -1];
+  int test1[__builtin_offsetof(type, a) == 0 ? 1 : -1];
+  int test2[__builtin_offsetof(type, b) == 4 ? 1 : -1];
+}





More information about the cfe-commits mailing list