Improve compatibility with GCC regarding inline semantics in GNU89

mode and in the presence of __gnu_inline__ attributes. This should fix
both PR3989 and PR4069.

As part of this, we now keep track of all of the attributes attached
to each declaration even after we've performed declaration
merging. This fixes PR3264.

llvm-svn: 70292
This commit is contained in:
Douglas Gregor
2009-04-28 06:37:30 +00:00
parent 7e09994cb8
commit 76fe50c654
8 changed files with 179 additions and 285 deletions

View File

@@ -240,9 +240,17 @@ GetLinkageForFunction(const FunctionDecl *FD, const LangOptions &Features) {
// If the inline function explicitly has the GNU inline attribute on it, or if
// this is C89 mode, we use to GNU semantics.
if (FD->hasAttr<GNUInlineAttr>() || (!Features.C99 && !Features.CPlusPlus)) {
if (!Features.C99 && !Features.CPlusPlus) {
// extern inline in GNU mode is like C99 inline.
if (FD->isC99InlineDefinition())
if (FD->getStorageClass() == FunctionDecl::Extern)
return CodeGenModule::GVA_C99Inline;
// Normal inline is a strong symbol.
return CodeGenModule::GVA_StrongExternal;
} else if (FD->hasActiveGNUInlineAttribute()) {
// GCC in C99 mode seems to use a different decision-making
// process for extern inline, which factors in previous
// declarations.
if (FD->isExternGNUInline())
return CodeGenModule::GVA_C99Inline;
// Normal inline is a strong symbol.
return CodeGenModule::GVA_StrongExternal;