Fixes for a couple of things:

- Declaration context of ParmVarDecls (that we got from the Declarator) was not their containing function.
- C++ out-of-line method definitions didn't get an access specifier.

Both were exposed by a crash when emitting a C++ method to a PCH file (assert at Decl::CheckAccessDeclContext()).

llvm-svn: 75597
This commit is contained in:
Argyrios Kyrtzidis 2009-07-14 03:18:53 +00:00
parent 2f0eff102c
commit 11a846ab53
2 changed files with 17 additions and 3 deletions

View File

@ -2298,8 +2298,12 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(Param->getLocation(), diag::err_param_typedef_of_void);
// FIXME: Leaks decl?
} else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
Params.push_back(FTI.ArgInfo[i].Param.getAs<ParmVarDecl>());
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
assert(Param->getDeclContext() != NewFD && "Was set before ?");
Param->setDeclContext(NewFD);
Params.push_back(Param);
}
}
} else if (const FunctionProtoType *FT = R->getAsFunctionProtoType()) {
@ -2546,8 +2550,11 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
if (FunctionTemplateDecl *OldTemplateDecl
= dyn_cast<FunctionTemplateDecl>(OldDecl))
NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl());
else
else {
if (isa<CXXMethodDecl>(NewFD)) // Set access for out-of-line definitions
NewFD->setAccess(OldDecl->getAccess());
NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
}
}
}

View File

@ -0,0 +1,7 @@
// RUN: clang-cc -emit-pch %s -o %t
struct S {
void m(int x);
};
void S::m(int x) { }