From: Eli Friedman Date: Wed, 7 Sep 2011 04:05:06 +0000 (+0000) Subject: Make sure the FunctionDecl's created by "#pragma weak" have correct ParmVarDecl's... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=900693b715b3832a42ae87157332baece94ccdd8;p=clang Make sure the FunctionDecl's created by "#pragma weak" have correct ParmVarDecl's. PR10878. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139224 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 1437469aeb..423f29f278 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5324,7 +5324,8 @@ public: void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType, SourceLocation PragmaLoc); - NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II); + NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, + SourceLocation Loc); void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W); /// ActOnPragmaWeakID - Called on well formed #pragma weak ident. diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 0483552c51..1119866352 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3631,17 +3631,40 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, /// DeclClonePragmaWeak - clone existing decl (maybe definition), /// #pragma weak needs a non-definition decl and source may not have one -NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { +NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, + SourceLocation Loc) { assert(isa(ND) || isa(ND)); NamedDecl *NewD = 0; if (FunctionDecl *FD = dyn_cast(ND)) { - NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), - FD->getInnerLocStart(), - FD->getLocation(), DeclarationName(II), - FD->getType(), FD->getTypeSourceInfo()); - if (FD->getQualifier()) { - FunctionDecl *NewFD = cast(NewD); + FunctionDecl *NewFD; + // FIXME: Missing call to CheckFunctionDeclaration(). + // FIXME: Mangling? + // FIXME: Is the qualifier info correct? + // FIXME: Is the DeclContext correct? + NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), + Loc, Loc, DeclarationName(II), + FD->getType(), FD->getTypeSourceInfo(), + SC_None, SC_None, + false/*isInlineSpecified*/, + FD->hasPrototype(), + false/*isConstexprSpecified*/); + NewD = NewFD; + + if (FD->getQualifier()) NewFD->setQualifierInfo(FD->getQualifierLoc()); + + // Fake up parameter variables; they are declared as if this were + // a typedef. + QualType FDTy = FD->getType(); + if (const FunctionProtoType *FT = FDTy->getAs()) { + SmallVector Params; + for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), + AE = FT->arg_type_end(); AI != AE; ++AI) { + ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); + Param->setScopeInfo(0, Params.size()); + Params.push_back(Param); + } + NewFD->setParams(Params.data(), Params.size()); } } else if (VarDecl *VD = dyn_cast(ND)) { NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), @@ -3664,7 +3687,7 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { W.setUsed(true); if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) IdentifierInfo *NDId = ND->getIdentifier(); - NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); + NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, NDId->getName())); NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); diff --git a/test/CodeGen/pragma-weak.c b/test/CodeGen/pragma-weak.c index 1de60e106a..7ad2b77d8e 100644 --- a/test/CodeGen/pragma-weak.c +++ b/test/CodeGen/pragma-weak.c @@ -136,7 +136,7 @@ void __both3(void) {} void __a1(void) __attribute((noinline)); #pragma weak a1 = __a1 void __a1(void) {} -// CHECK: define void @__a1() +// CHECK: define void @__a1() {{.*}} noinline // attributes introduced BEFORE a combination of #pragma weak and alias() // hold... @@ -144,13 +144,20 @@ void __a3(void) __attribute((noinline)); #pragma weak a3 = __a3 void a3(void) __attribute((alias("__a3"))); void __a3(void) {} -// CHECK: define void @__a3() +// CHECK: define void @__a3() {{.*}} noinline #pragma weak xxx = __xxx __attribute((pure,noinline,const,fastcall)) void __xxx(void) { } -// CHECK: void @__xxx() +// CHECK: void @__xxx() {{.*}} noinline -/// TODO: stuff that still doesn't work +///////////// PR10878: Make sure we can call a weak alias +void SHA512Pad(void *context) {} +#pragma weak SHA384Pad = SHA512Pad +void PR10878() { SHA384Pad(0); } +// CHECK: call void @SHA384Pad(i8* null) + + +///////////// TODO: stuff that still doesn't work // due to the fact that disparate TopLevelDecls cannot affect each other // (due to clang's Parser and ASTConsumer behavior, and quite reasonable)