[cfe-commits] r79570 - in /cfe/trunk: include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseTemplate.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/SemaTemplate/member-function-template.cpp
Douglas Gregor
dgregor at apple.com
Thu Aug 20 15:52:59 PDT 2009
Author: dgregor
Date: Thu Aug 20 17:52:58 2009
New Revision: 79570
URL: http://llvm.org/viewvc/llvm-project?rev=79570&view=rev
Log:
Initial support for parsing and representation of member function templates.
Added:
cfe/trunk/test/SemaTemplate/member-function-template.cpp
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Aug 20 17:52:58 2009
@@ -1276,6 +1276,7 @@
/// specifier on the function.
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
+ MultiTemplateParamsArg TemplateParameterLists,
ExprTy *BitfieldWidth,
ExprTy *Init,
bool Deleted = false) {
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Aug 20 17:52:58 2009
@@ -580,18 +580,6 @@
}
};
- void PushParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass);
- void DeallocateParsedClasses(ParsingClass *Class);
- void PopParsingClass();
-
- DeclPtrTy ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D);
- void ParseLexedMethodDeclarations(ParsingClass &Class);
- void ParseLexedMethodDefs(ParsingClass &Class);
- bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
- CachedTokens &Toks,
- tok::TokenKind EarlyAbortIf = tok::unknown,
- bool ConsumeFinalToken = true);
-
/// \brief Contains information about any template-specific
/// information that has been parsed prior to parsing declaration
/// specifiers.
@@ -628,6 +616,19 @@
/// instantiation.
SourceLocation TemplateLoc;
};
+
+ void PushParsingClass(DeclPtrTy TagOrTemplate, bool TopLevelClass);
+ void DeallocateParsedClasses(ParsingClass *Class);
+ void PopParsingClass();
+
+ DeclPtrTy ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
+ const ParsedTemplateInfo &TemplateInfo);
+ void ParseLexedMethodDeclarations(ParsingClass &Class);
+ void ParseLexedMethodDefs(ParsingClass &Class);
+ bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
+ CachedTokens &Toks,
+ tok::TokenKind EarlyAbortIf = tok::unknown,
+ bool ConsumeFinalToken = true);
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
@@ -1157,7 +1158,8 @@
AccessSpecifier AS = AS_none);
void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
DeclPtrTy TagDecl);
- void ParseCXXClassMemberDeclaration(AccessSpecifier AS);
+ void ParseCXXClassMemberDeclaration(AccessSpecifier AS,
+ const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Thu Aug 20 17:52:58 2009
@@ -21,17 +21,23 @@
/// Declarator is a well formed C++ inline method definition. Now lex its body
/// and store its tokens for parsing after the C++ class is complete.
Parser::DeclPtrTy
-Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
+Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
+ const ParsedTemplateInfo &TemplateInfo) {
assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
"This isn't a function declarator!");
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) &&
"Current token not a '{', ':' or 'try'!");
+ Action::MultiTemplateParamsArg TemplateParams(Actions,
+ TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
+ TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
DeclPtrTy FnD;
if (D.getDeclSpec().isFriendSpecified())
+ // FIXME: Friend templates
FnD = Actions.ActOnFriendDecl(CurScope, &D, /*IsDefinition*/ true);
- else
- FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0);
+ else // FIXME: pass template information through
+ FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D,
+ move(TemplateParams), 0, 0);
HandleMemberFunctionDefaultArgs(D, FnD);
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Aug 20 17:52:58 2009
@@ -905,15 +905,19 @@
/// constant-initializer:
/// '=' constant-expression
///
-void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
+void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
+ const ParsedTemplateInfo &TemplateInfo) {
// static_assert-declaration
if (Tok.is(tok::kw_static_assert)) {
+ // FIXME: Check for templates
SourceLocation DeclEnd;
ParseStaticAssertDeclaration(DeclEnd);
return;
}
if (Tok.is(tok::kw_template)) {
+ assert(!TemplateInfo.TemplateParams &&
+ "Nested template improperly parsed?");
SourceLocation DeclEnd;
ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
AS);
@@ -925,10 +929,12 @@
// __extension__ silences extension warnings in the subexpression.
ExtensionRAIIObject O(Diags); // Use RAII to do this.
ConsumeToken();
- return ParseCXXClassMemberDeclaration(AS);
+ return ParseCXXClassMemberDeclaration(AS, TemplateInfo);
}
if (Tok.is(tok::kw_using)) {
+ // FIXME: Check for template aliases
+
// Eat 'using'.
SourceLocation UsingLoc = ConsumeToken();
@@ -948,11 +954,12 @@
// decl-specifier-seq:
// Parse the common declaration-specifiers piece.
DeclSpec DS;
- ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_class);
+ ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
if (Tok.is(tok::semi)) {
ConsumeToken();
+ // FIXME: Friend templates?
if (DS.isFriendSpecified())
Actions.ActOnFriendDecl(CurScope, &DS, /*IsDefinition*/ false);
else
@@ -996,7 +1003,7 @@
return;
}
- ParseCXXInlineMethodDef(AS, DeclaratorInfo);
+ ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo);
return;
}
}
@@ -1059,15 +1066,20 @@
DeclPtrTy ThisDecl;
if (DS.isFriendSpecified()) {
- // TODO: handle initializers, bitfields, 'delete'
+ // TODO: handle initializers, bitfields, 'delete', friend templates
ThisDecl = Actions.ActOnFriendDecl(CurScope, &DeclaratorInfo,
/*IsDefinition*/ false);
- } else
+ } else {
+ Action::MultiTemplateParamsArg TemplateParams(Actions,
+ TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
+ TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
DeclaratorInfo,
+ move(TemplateParams),
BitfieldSize.release(),
Init.release(),
Deleted);
+ }
if (ThisDecl)
DeclsInGroup.push_back(ThisDecl);
@@ -1181,6 +1193,8 @@
continue;
}
+ // FIXME: Make sure we don't have a template here.
+
// Parse all the comma separated declarators.
ParseCXXClassMemberDeclaration(CurAS);
}
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Thu Aug 20 17:52:58 2009
@@ -151,6 +151,12 @@
assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
"Template information required");
+ if (Context == Declarator::MemberContext) {
+ // We are parsing a member template.
+ ParseCXXClassMemberDeclaration(AS, TemplateInfo);
+ return DeclPtrTy::make((void*)0);
+ }
+
// Parse the declaration specifiers.
DeclSpec DS;
// FIXME: Pass TemplateLoc through for explicit template instantiations
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Aug 20 17:52:58 2009
@@ -2038,6 +2038,7 @@
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
+ MultiTemplateParamsArg TemplateParameterLists,
ExprTy *BitfieldWidth,
ExprTy *Init,
bool Deleted = false);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=79570&r1=79569&r2=79570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 20 17:52:58 2009
@@ -550,6 +550,7 @@
/// any.
Sema::DeclPtrTy
Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
+ MultiTemplateParamsArg TemplateParameterLists,
ExprTy *BW, ExprTy *InitExpr, bool Deleted) {
const DeclSpec &DS = D.getDeclSpec();
DeclarationName Name = GetNameForDeclarator(D);
@@ -627,11 +628,13 @@
Decl *Member;
if (isInstField) {
+ // FIXME: Check for template parameters!
Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
AS);
assert(Member && "HandleField never returns null");
} else {
- Member = ActOnDeclarator(S, D).getAs<Decl>();
+ Member = HandleDeclarator(S, D, move(TemplateParameterLists), false)
+ .getAs<Decl>();
if (!Member) {
if (BitWidth) DeleteExpr(BitWidth);
return DeclPtrTy();
@@ -664,6 +667,11 @@
}
Member->setAccess(AS);
+
+ // If we have declared a member function template, set the access of the
+ // templated declaration as well.
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Member))
+ FunTmpl->getTemplatedDecl()->setAccess(AS);
}
assert((Name || isInstField) && "No identifier for non-field ?");
Added: cfe/trunk/test/SemaTemplate/member-function-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/member-function-template.cpp?rev=79570&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/member-function-template.cpp (added)
+++ cfe/trunk/test/SemaTemplate/member-function-template.cpp Thu Aug 20 17:52:58 2009
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only %s
+
+struct X {
+ template<typename T> T& f(T);
+};
More information about the cfe-commits
mailing list