]> granicus.if.org Git - clang/commitdiff
Fix AST representations of alias-declarations which define tag types. Inside classes...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 1 Jul 2011 19:46:12 +0000 (19:46 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 1 Jul 2011 19:46:12 +0000 (19:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134250 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
include/clang/Sema/Sema.h
lib/Parse/ParseDecl.cpp
lib/Parse/ParseDeclCXX.cpp
lib/Sema/SemaDecl.cpp
test/SemaTemplate/instantiate-function-2.cpp
test/SemaTemplate/instantiate-member-class.cpp

index 0b0946c0100c4caff8a133bc2ef320f0c1ad47e4..626ad5316d0d217586276fa77f3e8ff6ed2aac6d 100644 (file)
@@ -1450,7 +1450,7 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
                                   bool SuppressDeclarations = false);
 
-  void ParseSpecifierQualifierList(DeclSpec &DS);
+  void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none);
 
   void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, 
                                   ObjCTypeNameContext Context);
@@ -1628,7 +1628,9 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
   TypeResult ParseTypeName(SourceRange *Range = 0,
                            Declarator::TheContext Context
                              = Declarator::TypeNameContext,
-                           ObjCDeclSpec *objcQuals = 0);
+                           ObjCDeclSpec *objcQuals = 0,
+                           AccessSpecifier AS = AS_none,
+                           Decl **OwnedType = 0);
   void ParseBlockId();
 
   void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
@@ -1778,7 +1780,8 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
   Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
                                          const ParsedTemplateInfo &TemplateInfo,
                                          SourceLocation &DeclEnd,
-                                         ParsedAttributesWithRange &attrs);
+                                         ParsedAttributesWithRange &attrs,
+                                         Decl **OwnedType = 0);
   Decl *ParseUsingDirective(unsigned Context,
                             SourceLocation UsingLoc,
                             SourceLocation &DeclEnd,
@@ -1787,7 +1790,8 @@ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
                               const ParsedTemplateInfo &TemplateInfo,
                               SourceLocation UsingLoc,
                               SourceLocation &DeclEnd,
-                              AccessSpecifier AS = AS_none);
+                              AccessSpecifier AS = AS_none,
+                              Decl **OwnedType = 0);
   Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
   Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
                             SourceLocation AliasLoc, IdentifierInfo *Alias,
index 65ce34a7a2fbb8f321ebbf4c5fd181b31399b3bf..118130f8d94d97be23d11a1f76260494e2211469 100644 (file)
@@ -839,7 +839,7 @@ public:
   // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
   //
 
-  DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr);
+  DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = 0);
 
   void DiagnoseUseOfUnimplementedSelectors();
 
index 99441e0e0e3fd4d0a82cfd8679d1ee179eb03450..3b08469ca1a1d937b17bb040e44e26a34114b89e 100644 (file)
@@ -32,11 +32,15 @@ using namespace clang;
 /// Called type-id in C++.
 TypeResult Parser::ParseTypeName(SourceRange *Range,
                                  Declarator::TheContext Context,
-                                 ObjCDeclSpec *objcQuals) {
+                                 ObjCDeclSpec *objcQuals,
+                                 AccessSpecifier AS,
+                                 Decl **OwnedType) {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS(AttrFactory);
   DS.setObjCQualifiers(objcQuals);
-  ParseSpecifierQualifierList(DS);
+  ParseSpecifierQualifierList(DS, AS);
+  if (OwnedType)
+    *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
 
   // Parse the abstract-declarator, if present.
   Declarator DeclaratorInfo(DS, Context);
@@ -674,6 +678,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
   
   Decl *SingleDecl = 0;
+  Decl *OwnedType = 0;
   switch (Tok.getKind()) {
   case tok::kw_template:
   case tok::kw_export:
@@ -696,7 +701,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
     break;
   case tok::kw_using:
     SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
-                                                  DeclEnd, attrs);
+                                                  DeclEnd, attrs, &OwnedType);
     break;
   case tok::kw_static_assert:
   case tok::kw__Static_assert:
@@ -708,8 +713,9 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
   }
   
   // This routine returns a DeclGroup, if the thing we parsed only contains a
-  // single decl, convert it now.
-  return Actions.ConvertDeclToDeclGroup(SingleDecl);
+  // single decl, convert it now. Alias declarations can also declare a type;
+  // include that too if it is present.
+  return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
 }
 
 ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
@@ -1081,10 +1087,10 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
 ///          type-qualifier specifier-qualifier-list[opt]
 /// [GNU]    attributes     specifier-qualifier-list[opt]
 ///
-void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
+void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS) {
   /// specifier-qualifier-list is a subset of declaration-specifiers.  Just
   /// parse declaration-specifiers and complain about extra stuff.
-  ParseDeclarationSpecifiers(DS);
+  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS);
 
   // Validate declspec for type-name.
   unsigned Specs = DS.getParsedSpecifiers();
index b123461f1d5060f48e0addbbc3f364a7ddb8481d..d78f3728e1beeb61004ef0c521c6b9cc6bb4b372 100644 (file)
@@ -314,7 +314,8 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
 Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
                                          const ParsedTemplateInfo &TemplateInfo,
                                                SourceLocation &DeclEnd,
-                                             ParsedAttributesWithRange &attrs) {
+                                             ParsedAttributesWithRange &attrs,
+                                               Decl **OwnedType) {
   assert(Tok.is(tok::kw_using) && "Not using token");
 
   // Eat 'using'.
@@ -342,7 +343,8 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
   // Using declarations can't have attributes.
   ProhibitAttributes(attrs);
 
-  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd);
+  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
+                               AS_none, OwnedType);
 }
 
 /// ParseUsingDirective - Parse C++ using-directive, assumes
@@ -422,7 +424,8 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
                                     const ParsedTemplateInfo &TemplateInfo,
                                     SourceLocation UsingLoc,
                                     SourceLocation &DeclEnd,
-                                    AccessSpecifier AS) {
+                                    AccessSpecifier AS,
+                                    Decl **OwnedType) {
   CXXScopeSpec SS;
   SourceLocation TypenameLoc;
   bool IsTypeName;
@@ -511,7 +514,7 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
 
     TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
                               Declarator::AliasTemplateContext :
-                              Declarator::AliasDeclContext);
+                              Declarator::AliasDeclContext, 0, AS, OwnedType);
   } else
     // Parse (optional) attributes (most likely GNU strong-using extension).
     MaybeParseGNUAttributes(attrs);
index 8069eb438594ef052adfac00e457c4275c186f0c..ad1a62eb7fc0a9e570c30de88f7f9948f0b97754 100644 (file)
 using namespace clang;
 using namespace sema;
 
-Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr) {
+Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType) {
+  if (OwnedType) {
+    Decl *Group[2] = { OwnedType, Ptr };
+    return DeclGroupPtrTy::make(DeclGroupRef::Create(Context, Group, 2));
+  }
+
   return DeclGroupPtrTy::make(DeclGroupRef(Ptr));
 }
 
index b4c0d9d6393cfd3b28318f20453230b2062c8e5e..21eccd49013914e9cfdd9970d69f9e56dc759321 100644 (file)
@@ -42,3 +42,17 @@ namespace PR9654 {
     f<int>(0);
   }
 }
+
+namespace AliasTagDef {
+  template<typename T>
+  T f() {
+    using S = struct { // expected-warning {{C++0x}}
+      T g() {
+        return T();
+      }
+    };
+    return S().g();
+  }
+
+  int n = f<int>();
+}
index 74c2609dcd0f3ed160364d33311c953c87f0f343..1028b45cc0e1ff95e2e7b437fbc6c598b3f70d92 100644 (file)
@@ -104,3 +104,17 @@ namespace test2 {
   };
   template class C<int>;
 }
+
+namespace AliasTagDef {
+  template<typename T>
+  struct F {
+    using S = struct U { // expected-warning {{C++0x}}
+      T g() {
+        return T();
+      }
+    };
+  };
+
+  int m = F<int>::S().g();
+  int n = F<int>::U().g();
+}