forked from OSchip/llvm-project
implement the alias attirbute (in both Sema and Codegen)
llvm-svn: 52092
This commit is contained in:
parent
486c7d3fa5
commit
b6f7953818
|
@ -23,6 +23,7 @@ namespace clang {
|
|||
class Attr {
|
||||
public:
|
||||
enum Kind {
|
||||
Alias,
|
||||
Aligned,
|
||||
Packed,
|
||||
Annotate,
|
||||
|
@ -106,7 +107,20 @@ public:
|
|||
}
|
||||
static bool classof(const AnnotateAttr *A) { return true; }
|
||||
};
|
||||
|
||||
|
||||
class AliasAttr : public Attr {
|
||||
std::string Aliasee;
|
||||
public:
|
||||
AliasAttr(const std::string &aliasee) : Attr(Alias), Aliasee(aliasee) {}
|
||||
|
||||
const std::string& getAliasee() const { return Aliasee; }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
|
||||
static bool classof(const Attr *A) { return A->getKind() == Alias; }
|
||||
static bool classof(const AliasAttr *A) { return true; }
|
||||
};
|
||||
|
||||
class NoReturnAttr : public Attr {
|
||||
public:
|
||||
NoReturnAttr() : Attr(NoReturn) {}
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
|
||||
enum Kind { // Please keep this list alphabetized.
|
||||
AT_address_space,
|
||||
AT_alias,
|
||||
AT_aligned,
|
||||
AT_annotate,
|
||||
AT_deprecated,
|
||||
|
|
|
@ -188,6 +188,24 @@ bool hasAggregateLLVMType(QualType T) {
|
|||
!T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
|
||||
}
|
||||
|
||||
void CodeGenModule::SetGlobalValueAttributes(const FunctionDecl *FD,
|
||||
llvm::GlobalValue *GV) {
|
||||
// TODO: Set up linkage and many other things. Note, this is a simple
|
||||
// approximation of what we really want.
|
||||
if (FD->getStorageClass() == FunctionDecl::Static)
|
||||
GV->setLinkage(llvm::Function::InternalLinkage);
|
||||
else if (FD->getAttr<DLLImportAttr>())
|
||||
GV->setLinkage(llvm::Function::DLLImportLinkage);
|
||||
else if (FD->getAttr<DLLExportAttr>())
|
||||
GV->setLinkage(llvm::Function::DLLExportLinkage);
|
||||
else if (FD->getAttr<WeakAttr>() || FD->isInline())
|
||||
GV->setLinkage(llvm::Function::WeakLinkage);
|
||||
|
||||
if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
|
||||
CodeGenModule::setVisibility(GV, attr->getVisibility());
|
||||
// FIXME: else handle -fvisibility
|
||||
}
|
||||
|
||||
void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
|
||||
llvm::Function *F,
|
||||
const llvm::FunctionType *FTy) {
|
||||
|
@ -230,20 +248,7 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
|
|||
if (FD->getAttr<FastCallAttr>())
|
||||
F->setCallingConv(llvm::CallingConv::Fast);
|
||||
|
||||
// TODO: Set up linkage and many other things. Note, this is a simple
|
||||
// approximation of what we really want.
|
||||
if (FD->getStorageClass() == FunctionDecl::Static)
|
||||
F->setLinkage(llvm::Function::InternalLinkage);
|
||||
else if (FD->getAttr<DLLImportAttr>())
|
||||
F->setLinkage(llvm::Function::DLLImportLinkage);
|
||||
else if (FD->getAttr<DLLExportAttr>())
|
||||
F->setLinkage(llvm::Function::DLLExportLinkage);
|
||||
else if (FD->getAttr<WeakAttr>() || FD->isInline())
|
||||
F->setLinkage(llvm::Function::WeakLinkage);
|
||||
|
||||
if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
|
||||
CodeGenModule::setVisibility(F, attr->getVisibility());
|
||||
// FIXME: else handle -fvisibility
|
||||
SetGlobalValueAttributes(FD, F);
|
||||
}
|
||||
|
||||
|
||||
|
@ -263,8 +268,20 @@ llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
|
|||
// If it doesn't already exist, just create and return an entry.
|
||||
if (F == 0) {
|
||||
// FIXME: param attributes for sext/zext etc.
|
||||
F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
|
||||
D->getName(), &getModule());
|
||||
if (D->getBody() || !D->getAttr<AliasAttr>())
|
||||
F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage,
|
||||
D->getName(), &getModule());
|
||||
else {
|
||||
const std::string& aliaseeName = D->getAttr<AliasAttr>()->getAliasee();
|
||||
llvm::Function *aliasee = getModule().getFunction(aliaseeName);
|
||||
llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(),
|
||||
llvm::Function::ExternalLinkage,
|
||||
D->getName(),
|
||||
aliasee,
|
||||
&getModule());
|
||||
SetGlobalValueAttributes(D, alias);
|
||||
return Entry = alias;
|
||||
}
|
||||
|
||||
SetFunctionAttributes(D, F, FTy);
|
||||
return Entry = F;
|
||||
|
@ -494,8 +511,11 @@ void CodeGenModule::EmitObjCClassImplementation(
|
|||
|
||||
void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
|
||||
// If this is not a prototype, emit the body.
|
||||
if (!FD->isThisDeclarationADefinition())
|
||||
if (!FD->isThisDeclarationADefinition()) {
|
||||
if (FD->getAttr<AliasAttr>())
|
||||
GetAddrOfFunctionDecl(FD, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the function is a static, defer code generation until later so we can
|
||||
// easily omit unused statics.
|
||||
|
@ -534,6 +554,8 @@ void CodeGenModule::EmitStatics() {
|
|||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
if (FD->getBody())
|
||||
CodeGenFunction(*this).GenerateCode(FD);
|
||||
else if (FD->getAttr<AliasAttr>())
|
||||
GetAddrOfFunctionDecl(FD, true);
|
||||
} else {
|
||||
EmitGlobalVarInit(cast<VarDecl>(D));
|
||||
}
|
||||
|
|
|
@ -154,6 +154,9 @@ private:
|
|||
void SetFunctionAttributes(const FunctionDecl *FD,
|
||||
llvm::Function *F,
|
||||
const llvm::FunctionType *FTy);
|
||||
|
||||
void SetGlobalValueAttributes(const FunctionDecl *FD,
|
||||
llvm::GlobalValue *GV);
|
||||
|
||||
};
|
||||
} // end namespace CodeGen
|
||||
|
|
|
@ -56,6 +56,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
if (!memcmp(Str, "pure", 4)) return AT_pure;
|
||||
if (!memcmp(Str, "mode", 4)) return AT_mode;
|
||||
break;
|
||||
case 5:
|
||||
if (!memcmp(Str, "alias", 5)) return AT_alias;
|
||||
break;
|
||||
case 6:
|
||||
if (!memcmp(Str, "packed", 6)) return AT_packed;
|
||||
if (!memcmp(Str, "malloc", 6)) return AT_malloc;
|
||||
|
|
|
@ -319,6 +319,7 @@ private:
|
|||
void HandleExtVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr);
|
||||
|
||||
void HandleAlignedAttribute(Decl *d, AttributeList *rawAttr);
|
||||
void HandleAliasAttribute(Decl *d, AttributeList *rawAttr);
|
||||
void HandlePackedAttribute(Decl *d, AttributeList *rawAttr);
|
||||
void HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr);
|
||||
void HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr);
|
||||
|
|
|
@ -2250,6 +2250,9 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *Attr) {
|
|||
}
|
||||
// FIXME: Diagnostic?
|
||||
break;
|
||||
case AttributeList::AT_alias:
|
||||
HandleAliasAttribute(New, Attr);
|
||||
break;
|
||||
case AttributeList::AT_deprecated:
|
||||
HandleDeprecatedAttribute(New, Attr);
|
||||
break;
|
||||
|
@ -2438,6 +2441,32 @@ void Sema::HandlePackedAttribute(Decl *d, AttributeList *rawAttr) {
|
|||
rawAttr->getName()->getName());
|
||||
}
|
||||
|
||||
void Sema::HandleAliasAttribute(Decl *d, AttributeList *rawAttr) {
|
||||
// check the attribute arguments.
|
||||
if (rawAttr->getNumArgs() != 1) {
|
||||
Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
|
||||
std::string("1"));
|
||||
return;
|
||||
}
|
||||
|
||||
Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
|
||||
Arg = Arg->IgnoreParenCasts();
|
||||
StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
|
||||
|
||||
if (Str == 0 || Str->isWide()) {
|
||||
Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
|
||||
"alias", std::string("1"));
|
||||
return;
|
||||
}
|
||||
|
||||
const char *Alias = Str->getStrData();
|
||||
unsigned AliasLen = Str->getByteLength();
|
||||
|
||||
// FIXME: check if target symbol exists in current file
|
||||
|
||||
d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
|
||||
}
|
||||
|
||||
void Sema::HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr) {
|
||||
// check the attribute arguments.
|
||||
if (rawAttr->getNumArgs() != 0) {
|
||||
|
|
|
@ -24,3 +24,7 @@ int t6 __attribute__((visibility("protected")));
|
|||
// RUN: clang -emit-llvm < %s | grep 't7.*nounwind'
|
||||
void t7() __attribute__((noreturn, nothrow));
|
||||
void t7() {}
|
||||
|
||||
// RUN: clang -emit-llvm < %s | grep 't9.*alias.*weak.*t8'
|
||||
void __t8() {}
|
||||
void t9() __attribute__((weak, alias("__t8")));
|
||||
|
|
Loading…
Reference in New Issue