diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-04 17:13:46 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-04 17:13:46 +0000 |
commit | b258569405a020161fb8991913f03b938987dab5 (patch) | |
tree | 0e0bb1baedc042fbe09ab6fd7f3775163caf3986 /clang/lib/Serialization | |
parent | 9b7b39116ea07aea979ea49c4ec32ded85a5019f (diff) | |
download | bcm5719-llvm-b258569405a020161fb8991913f03b938987dab5.tar.gz bcm5719-llvm-b258569405a020161fb8991913f03b938987dab5.zip |
Implement declaration merging for non-template functions from
different modules. This implementation is a first approximation of
what we want, using only the function type to determine
equivalence. Later, we'll want to deal with some of the more subtle
issues, including:
- C allows a prototyped declaration and a non-prototyped declaration
to be merged, which we should support
- We may want to ignore the return type when merging, then
complain if the return types differ. Or, we may want to leave it
as it us, so that we only complain if overload resolution
eventually fails.
- C++ non-static member functions need to consider cv-qualifiers
and ref-qualifiers.
- Function templates need to consider the template parameters and
return type.
- Function template specializations will have special rules.
- We can now (accidentally!) end up overloading in C, even without
the "overloadable" attribute, and will need to detect this at some
point.
The actual detection of "is this an overload?" is implemented by
Sema::IsOverload(), which will need to be moved into the AST library
for re-use here. That will be a future refactor.
llvm-svn: 147534
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 62 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 39 |
2 files changed, 57 insertions, 44 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index c00b69cf75b..c34243f6016 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -490,14 +490,38 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { } void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { - VisitRedeclarable(FD); + // Record the declaration -> global ID mapping. + Reader.DeclToID[FD] = ThisDeclID; + + RedeclarableResult Redecl = VisitRedeclarable(FD); VisitDeclaratorDecl(FD); ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx); FD->IdentifierNamespace = Record[Idx++]; + + // FunctionDecl's body is handled last at ASTDeclReader::Visit, + // after everything else is read. + + FD->SClass = (StorageClass)Record[Idx++]; + FD->SClassAsWritten = (StorageClass)Record[Idx++]; + FD->IsInline = Record[Idx++]; + FD->IsInlineSpecified = Record[Idx++]; + FD->IsVirtualAsWritten = Record[Idx++]; + FD->IsPure = Record[Idx++]; + FD->HasInheritedPrototype = Record[Idx++]; + FD->HasWrittenPrototype = Record[Idx++]; + FD->IsDeleted = Record[Idx++]; + FD->IsTrivial = Record[Idx++]; + FD->IsDefaulted = Record[Idx++]; + FD->IsExplicitlyDefaulted = Record[Idx++]; + FD->HasImplicitReturnZero = Record[Idx++]; + FD->IsConstexpr = Record[Idx++]; + FD->EndRangeLoc = ReadSourceLocation(Record, Idx); + switch ((FunctionDecl::TemplatedKind)Record[Idx++]) { default: llvm_unreachable("Unhandled TemplatedKind!"); case FunctionDecl::TK_NonTemplate: + mergeRedeclarable(FD, Redecl); break; case FunctionDecl::TK_FunctionTemplate: FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>(Record, @@ -591,25 +615,6 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { } } - // FunctionDecl's body is handled last at ASTDeclReader::Visit, - // after everything else is read. - - FD->SClass = (StorageClass)Record[Idx++]; - FD->SClassAsWritten = (StorageClass)Record[Idx++]; - FD->IsInline = Record[Idx++]; - FD->IsInlineSpecified = Record[Idx++]; - FD->IsVirtualAsWritten = Record[Idx++]; - FD->IsPure = Record[Idx++]; - FD->HasInheritedPrototype = Record[Idx++]; - FD->HasWrittenPrototype = Record[Idx++]; - FD->IsDeleted = Record[Idx++]; - FD->IsTrivial = Record[Idx++]; - FD->IsDefaulted = Record[Idx++]; - FD->IsExplicitlyDefaulted = Record[Idx++]; - FD->HasImplicitReturnZero = Record[Idx++]; - FD->IsConstexpr = Record[Idx++]; - FD->EndRangeLoc = ReadSourceLocation(Record, Idx); - // Read in the parameters. unsigned NumParams = Record[Idx++]; SmallVector<ParmVarDecl *, 16> Params; @@ -1696,12 +1701,19 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { // Compatible tags match. if (TagDecl *TagX = dyn_cast<TagDecl>(X)) { TagDecl *TagY = cast<TagDecl>(Y); - if ((TagX->getTagKind() == TagY->getTagKind()) || - ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class)&& - (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class))) - return true; + return (TagX->getTagKind() == TagY->getTagKind()) || + ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class) && + (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class)); } - + + // Functions with the same type and linkage match. + if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) { + FunctionDecl *FuncY = cast<FunctionDecl>(Y); + return (FuncX->getLinkage() == FuncY->getLinkage()) && + FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType()); + } + + // FIXME: Many other cases to implement. return false; } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index a995e37ee7b..f6c65f0870b 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -302,6 +302,26 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record); Record.push_back(D->getIdentifierNamespace()); + + // FunctionDecl's body is handled last at ASTWriterDecl::Visit, + // after everything else is written. + + Record.push_back(D->getStorageClass()); // FIXME: stable encoding + Record.push_back(D->getStorageClassAsWritten()); + Record.push_back(D->IsInline); + Record.push_back(D->isInlineSpecified()); + Record.push_back(D->isVirtualAsWritten()); + Record.push_back(D->isPure()); + Record.push_back(D->hasInheritedPrototype()); + Record.push_back(D->hasWrittenPrototype()); + Record.push_back(D->isDeletedAsWritten()); + Record.push_back(D->isTrivial()); + Record.push_back(D->isDefaulted()); + Record.push_back(D->isExplicitlyDefaulted()); + Record.push_back(D->hasImplicitReturnZero()); + Record.push_back(D->isConstexpr()); + Writer.AddSourceLocation(D->getLocEnd(), Record); + Record.push_back(D->getTemplatedKind()); switch (D->getTemplatedKind()) { default: llvm_unreachable("Unhandled TemplatedKind!"); @@ -368,25 +388,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { } } - // FunctionDecl's body is handled last at ASTWriterDecl::Visit, - // after everything else is written. - - Record.push_back(D->getStorageClass()); // FIXME: stable encoding - Record.push_back(D->getStorageClassAsWritten()); - Record.push_back(D->IsInline); - Record.push_back(D->isInlineSpecified()); - Record.push_back(D->isVirtualAsWritten()); - Record.push_back(D->isPure()); - Record.push_back(D->hasInheritedPrototype()); - Record.push_back(D->hasWrittenPrototype()); - Record.push_back(D->isDeletedAsWritten()); - Record.push_back(D->isTrivial()); - Record.push_back(D->isDefaulted()); - Record.push_back(D->isExplicitlyDefaulted()); - Record.push_back(D->hasImplicitReturnZero()); - Record.push_back(D->isConstexpr()); - Writer.AddSourceLocation(D->getLocEnd(), Record); - Record.push_back(D->param_size()); for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end(); P != PEnd; ++P) |