diff options
-rw-r--r-- | include/clang/Parse/Parser.h | 12 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 20 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-function-2.cpp | 14 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-member-class.cpp | 14 |
7 files changed, 63 insertions, 17 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 0b0946c010..626ad5316d 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -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, diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 65ce34a7a2..118130f8d9 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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(); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 99441e0e0e..3b08469ca1 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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(); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index b123461f1d..d78f3728e1 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8069eb4385..ad1a62eb7f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -45,7 +45,12 @@ 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)); } diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp index b4c0d9d639..21eccd4901 100644 --- a/test/SemaTemplate/instantiate-function-2.cpp +++ b/test/SemaTemplate/instantiate-function-2.cpp @@ -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>(); +} diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp index 74c2609dcd..1028b45cc0 100644 --- a/test/SemaTemplate/instantiate-member-class.cpp +++ b/test/SemaTemplate/instantiate-member-class.cpp @@ -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(); +} |