aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Parse/Parser.h12
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Parse/ParseDecl.cpp20
-rw-r--r--lib/Parse/ParseDeclCXX.cpp11
-rw-r--r--lib/Sema/SemaDecl.cpp7
-rw-r--r--test/SemaTemplate/instantiate-function-2.cpp14
-rw-r--r--test/SemaTemplate/instantiate-member-class.cpp14
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();
+}