forked from OSchip/llvm-project
Start propagating template parameter lists to the right places to
handle function templates. There's no actual code for function templates yet, but at least we complain about typedef templates. llvm-svn: 74021
This commit is contained in:
parent
349db7bbcd
commit
b52fabb2a8
|
@ -651,6 +651,7 @@ def note_template_export_unsupported : Note<
|
|||
def err_template_outside_namespace_or_class_scope : Error<
|
||||
"templates can only be declared in namespace or class scope">;
|
||||
def err_template_linkage : Error<"templates must have C++ linkage">;
|
||||
def err_template_typedef : Error<"a typedef cannot be a template">;
|
||||
def err_template_unnamed_class : Error<
|
||||
"cannot declare a class template with no name">;
|
||||
def err_template_param_list_different_arity : Error<
|
||||
|
|
|
@ -1453,6 +1453,18 @@ public:
|
|||
return DeclResult();
|
||||
}
|
||||
|
||||
/// \brief Invoked when a declarator that has one or more template parameter
|
||||
/// lists has been parsed.
|
||||
///
|
||||
/// This action is similar to ActOnDeclarator(), except that the declaration
|
||||
/// being created somehow involves a template, e.g., it is a template
|
||||
/// declaration or specialization.
|
||||
virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
|
||||
MultiTemplateParamsArg TemplateParameterLists,
|
||||
Declarator &D) {
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
/// \brief Process the explicit instantiation of a class template
|
||||
/// specialization.
|
||||
///
|
||||
|
|
|
@ -909,7 +909,8 @@ private:
|
|||
DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
|
||||
SourceLocation &DeclEnd,
|
||||
bool RequireSemi = true);
|
||||
DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D);
|
||||
DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D,
|
||||
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
|
||||
DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
|
||||
DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
|
||||
DeclPtrTy ParseFunctionTryBlock(DeclPtrTy Decl);
|
||||
|
|
|
@ -371,7 +371,8 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
|
|||
/// According to the standard grammar, =default and =delete are function
|
||||
/// definitions, but that definitely doesn't fit with the parser here.
|
||||
///
|
||||
Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D) {
|
||||
Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
|
||||
const ParsedTemplateInfo &TemplateInfo) {
|
||||
// If a simple-asm-expr is present, parse it.
|
||||
if (Tok.is(tok::kw_asm)) {
|
||||
SourceLocation Loc;
|
||||
|
@ -393,7 +394,13 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D) {
|
|||
}
|
||||
|
||||
// Inform the current actions module that we just parsed this declarator.
|
||||
DeclPtrTy ThisDecl = Actions.ActOnDeclarator(CurScope, D);
|
||||
DeclPtrTy ThisDecl = TemplateInfo.TemplateParams?
|
||||
Actions.ActOnTemplateDeclarator(CurScope,
|
||||
Action::MultiTemplateParamsArg(Actions,
|
||||
TemplateInfo.TemplateParams->data(),
|
||||
TemplateInfo.TemplateParams->size()),
|
||||
D)
|
||||
: Actions.ActOnDeclarator(CurScope, D);
|
||||
|
||||
// Parse declarator '=' initializer.
|
||||
if (Tok.is(tok::equal)) {
|
||||
|
|
|
@ -170,7 +170,8 @@ Parser::ParseSingleDeclarationAfterTemplate(
|
|||
// If we have a declaration or declarator list, handle it.
|
||||
if (isDeclarationAfterDeclarator()) {
|
||||
// Parse this declaration.
|
||||
DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo);
|
||||
DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
|
||||
TemplateInfo);
|
||||
|
||||
if (Tok.is(tok::comma)) {
|
||||
Diag(Tok, diag::err_multiple_template_declarators)
|
||||
|
|
|
@ -421,9 +421,12 @@ public:
|
|||
virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
|
||||
|
||||
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
|
||||
return ActOnDeclarator(S, D, false);
|
||||
return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
|
||||
}
|
||||
DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition);
|
||||
|
||||
DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
|
||||
MultiTemplateParamsArg TemplateParameterLists,
|
||||
bool IsFunctionDefinition);
|
||||
void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
|
||||
Scope *S);
|
||||
void DiagnoseFunctionSpecifiers(Declarator& D);
|
||||
|
@ -437,6 +440,7 @@ public:
|
|||
bool &Redeclaration);
|
||||
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, NamedDecl* PrevDecl,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool IsFunctionDefinition,
|
||||
bool &Redeclaration);
|
||||
void CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
|
||||
|
@ -2068,6 +2072,10 @@ public:
|
|||
AttributeList *Attr,
|
||||
MultiTemplateParamsArg TemplateParameterLists);
|
||||
|
||||
virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
|
||||
MultiTemplateParamsArg TemplateParameterLists,
|
||||
Declarator &D);
|
||||
|
||||
virtual DeclResult
|
||||
ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
||||
unsigned TagSpec,
|
||||
|
|
|
@ -1385,7 +1385,9 @@ static bool isNearlyMatchingFunction(ASTContext &Context,
|
|||
}
|
||||
|
||||
Sema::DeclPtrTy
|
||||
Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
|
||||
Sema::HandleDeclarator(Scope *S, Declarator &D,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool IsFunctionDefinition) {
|
||||
DeclarationName Name = GetNameForDeclarator(D);
|
||||
|
||||
// All of these full declarators require an identifier. If it doesn't have
|
||||
|
@ -1500,9 +1502,15 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
|
|||
|
||||
bool Redeclaration = false;
|
||||
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
||||
if (TemplateParamLists.size()) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_template_typedef);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
New = ActOnTypedefDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
|
||||
} else if (R->isFunctionType()) {
|
||||
New = ActOnFunctionDeclarator(S, D, DC, R, PrevDecl,
|
||||
move(TemplateParamLists),
|
||||
IsFunctionDefinition, Redeclaration);
|
||||
} else {
|
||||
New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
|
||||
|
@ -1987,6 +1995,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
|||
NamedDecl*
|
||||
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, NamedDecl* PrevDecl,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool IsFunctionDefinition, bool &Redeclaration) {
|
||||
assert(R.getTypePtr()->isFunctionType());
|
||||
|
||||
|
@ -2044,6 +2053,11 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
<< R->getAsFunctionType()->getResultType();
|
||||
D.setInvalidType();
|
||||
}
|
||||
|
||||
// Check that we can declare a template here.
|
||||
if (TemplateParamLists.size() &&
|
||||
CheckTemplateDeclScope(S, TemplateParamLists))
|
||||
return 0;
|
||||
|
||||
bool isVirtualOkay = false;
|
||||
FunctionDecl *NewFD;
|
||||
|
@ -2987,7 +3001,9 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
|
|||
|
||||
Scope *ParentScope = FnBodyScope->getParent();
|
||||
|
||||
DeclPtrTy DP = ActOnDeclarator(ParentScope, D, /*IsFunctionDefinition=*/true);
|
||||
DeclPtrTy DP = HandleDeclarator(ParentScope, D,
|
||||
MultiTemplateParamsArg(*this),
|
||||
/*IsFunctionDefinition=*/true);
|
||||
return ActOnStartOfFunctionDef(FnBodyScope, DP);
|
||||
}
|
||||
|
||||
|
|
|
@ -2499,6 +2499,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
return DeclPtrTy::make(Specialization);
|
||||
}
|
||||
|
||||
Sema::DeclPtrTy
|
||||
Sema::ActOnTemplateDeclarator(Scope *S,
|
||||
MultiTemplateParamsArg TemplateParameterLists,
|
||||
Declarator &D) {
|
||||
return HandleDeclarator(S, D, move(TemplateParameterLists), false);
|
||||
}
|
||||
|
||||
// Explicit instantiation of a class template specialization
|
||||
Sema::DeclResult
|
||||
Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
template<typename T> typedef T X; // expected-error{{typedef cannot be a template}}
|
Loading…
Reference in New Issue