diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-09-07 04:05:06 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-09-07 04:05:06 +0000 |
commit | ce3e2c85b1c010df6907979a68e6147f266d727d (patch) | |
tree | 3233856d3879170045bf819bc2cc023360dd6b04 /clang/lib | |
parent | 9d4fac0f9fa36299897f511bbb405be56c7ada3d (diff) | |
download | bcm5719-llvm-ce3e2c85b1c010df6907979a68e6147f266d727d.tar.gz bcm5719-llvm-ce3e2c85b1c010df6907979a68e6147f266d727d.zip |
Make sure the FunctionDecl's created by "#pragma weak" have correct ParmVarDecl's. PR10878.
llvm-svn: 139224
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0483552c519..11198663520 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/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<FunctionDecl>(ND) || isa<VarDecl>(ND)); NamedDecl *NewD = 0; if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { - NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), - FD->getInnerLocStart(), - FD->getLocation(), DeclarationName(II), - FD->getType(), FD->getTypeSourceInfo()); - if (FD->getQualifier()) { - FunctionDecl *NewFD = cast<FunctionDecl>(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<FunctionProtoType>()) { + SmallVector<ParmVarDecl*, 16> 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<VarDecl>(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)); |