summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-07-01 19:46:12 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-07-01 19:46:12 +0000
commitcd1c0555286ff5aec940802f27a46fd1bae8aee7 (patch)
tree8f6710ea14d2afb67546b41113b8930925f18fff
parent5a33687da07cb8ffc68ef5065ed46bab5c4d6555 (diff)
downloadbcm5719-llvm-cd1c0555286ff5aec940802f27a46fd1bae8aee7.tar.gz
bcm5719-llvm-cd1c0555286ff5aec940802f27a46fd1bae8aee7.zip
Fix AST representations of alias-declarations which define tag types. Inside classes, the tag types need to have an associated access specifier, and inside function definitions, they need to be included in the declarations of the DeclStmt. These issues manifested as assertions during template instantiation, and also in a WIP constexpr patch.
llvm-svn: 134250
-rw-r--r--clang/include/clang/Parse/Parser.h12
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/lib/Parse/ParseDecl.cpp20
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp11
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
-rw-r--r--clang/test/SemaTemplate/instantiate-function-2.cpp14
-rw-r--r--clang/test/SemaTemplate/instantiate-member-class.cpp14
7 files changed, 63 insertions, 17 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 0b0946c0100..626ad5316d0 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/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/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 65ce34a7a2f..118130f8d94 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/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/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 99441e0e0e3..3b08469ca1a 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/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/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index b123461f1d5..d78f3728e1b 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8069eb43859..ad1a62eb7fc 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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/clang/test/SemaTemplate/instantiate-function-2.cpp b/clang/test/SemaTemplate/instantiate-function-2.cpp
index b4c0d9d6393..21eccd49013 100644
--- a/clang/test/SemaTemplate/instantiate-function-2.cpp
+++ b/clang/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/clang/test/SemaTemplate/instantiate-member-class.cpp b/clang/test/SemaTemplate/instantiate-member-class.cpp
index 74c2609dcd0..1028b45cc0e 100644
--- a/clang/test/SemaTemplate/instantiate-member-class.cpp
+++ b/clang/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();
+}
OpenPOWER on IntegriCloud