[cfe-commits] r55966 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/PR2743-reference-missing-static.c test/CodeGen/rdr-6095112-alias-references-inline.c test/CodeGen/rdr-6140807-alias-references-forward.c
Daniel Dunbar
daniel at zuster.org
Mon Sep 8 16:44:32 PDT 2008
Author: ddunbar
Date: Mon Sep 8 18:44:31 2008
New Revision: 55966
URL: http://llvm.org/viewvc/llvm-project?rev=55966&view=rev
Log:
Fix a number of issues w.r.t. emission of global for functions and
aliases.
- Attributes specific to a definition are only set when the
definition is seen.
- Alias generation is delayed until the end of the module; necessary
since the alias may reference forward.
- Fixes: PR2743, <rdr://6140807&6094512>
- Improves: <rdr://6095112> (added XFAIL)
Also, print module on verification failures.
Added:
cfe/trunk/test/CodeGen/PR2743-reference-missing-static.c
cfe/trunk/test/CodeGen/rdr-6095112-alias-references-inline.c
cfe/trunk/test/CodeGen/rdr-6140807-alias-references-forward.c
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=55966&r1=55965&r2=55966&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Sep 8 18:44:31 2008
@@ -56,6 +56,7 @@
void CodeGenModule::Release() {
EmitStatics();
+ EmitAliases();
if (Runtime)
if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
AddGlobalCtor(ObjCInitFunction);
@@ -63,7 +64,10 @@
EmitCtorList(GlobalDtors, "llvm.global_dtors");
EmitAnnotations();
// Run the verifier to check that the generated code is consistent.
- assert(!verifyModule(TheModule));
+ if (verifyModule(TheModule, llvm::PrintMessageAction)) {
+ TheModule.dump();
+ assert(0 && "Module failed verification!");
+ }
}
/// ErrorUnsupported - Print out an error that codegen doesn't support the
@@ -176,18 +180,25 @@
static void SetGlobalValueAttributes(const Decl *D,
bool IsInternal,
bool IsInline,
- llvm::GlobalValue *GV) {
+ llvm::GlobalValue *GV,
+ bool ForDefinition) {
// TODO: Set up linkage and many other things. Note, this is a simple
// approximation of what we really want.
- if (IsInternal) {
- GV->setLinkage(llvm::Function::InternalLinkage);
- } else {
+ if (!ForDefinition) {
+ // Only a few attributes are set on declarations.
if (D->getAttr<DLLImportAttr>())
GV->setLinkage(llvm::Function::DLLImportLinkage);
- else if (D->getAttr<DLLExportAttr>())
- GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->getAttr<WeakAttr>() || IsInline)
- GV->setLinkage(llvm::Function::WeakLinkage);
+ } else {
+ if (IsInternal) {
+ GV->setLinkage(llvm::Function::InternalLinkage);
+ } else {
+ if (D->getAttr<DLLImportAttr>())
+ GV->setLinkage(llvm::Function::DLLImportLinkage);
+ else if (D->getAttr<DLLExportAttr>())
+ GV->setLinkage(llvm::Function::DLLExportLinkage);
+ else if (D->getAttr<WeakAttr>() || IsInline)
+ GV->setLinkage(llvm::Function::WeakLinkage);
+ }
}
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
@@ -201,7 +212,7 @@
}
}
-static void SetFunctionAttrs(const CGFunctionInfo &Info, llvm::Function *F) {
+static void SetFunctionParamAttrs(const CGFunctionInfo &Info, llvm::Function *F) {
ParamAttrListType ParamAttrList;
Info.constructParamAttrList(ParamAttrList);
@@ -215,26 +226,79 @@
/// SetFunctionAttributesForDefinition - Set function attributes
/// specific to a function definition.
-void CodeGenModule::SetFunctionAttributesForDefinition(llvm::Function *F) {
+void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D,
+ llvm::Function *F) {
+ if (isa<ObjCMethodDecl>(D)) {
+ SetGlobalValueAttributes(D, true, false, F, true);
+ } else {
+ const FunctionDecl *FD = cast<FunctionDecl>(D);
+ SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
+ FD->isInline(), F, true);
+ }
+
if (!Features.Exceptions)
F->addParamAttr(0, llvm::ParamAttr::NoUnwind);
}
void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD,
llvm::Function *F) {
- SetFunctionAttrs(CGFunctionInfo(MD, Context), F);
+ SetFunctionParamAttrs(CGFunctionInfo(MD, Context), F);
- SetFunctionAttributesForDefinition(F);
-
- SetGlobalValueAttributes(MD, true, false, F);
+ SetFunctionAttributesForDefinition(MD, F);
}
void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
llvm::Function *F) {
- SetFunctionAttrs(CGFunctionInfo(FD), F);
+ SetFunctionParamAttrs(CGFunctionInfo(FD), F);
+
+ SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
+ FD->isInline(), F, false);
+}
+
+void CodeGenModule::EmitAliases() {
+ for (unsigned i = 0, e = Aliases.size(); i != e; ++i) {
+ const FunctionDecl *D = Aliases[i];
+ const AliasAttr *AA = D->getAttr<AliasAttr>();
+
+ // This is something of a hack, if the FunctionDecl got overridden
+ // then its attributes will be moved to the new declaration. In
+ // this case the current decl has no alias attribute, but we will
+ // eventually see it.
+ if (!AA)
+ continue;
+
+ const std::string& aliaseeName = AA->getAliasee();
+ llvm::Function *aliasee = getModule().getFunction(aliaseeName);
+ if (!aliasee) {
+ // FIXME: This isn't unsupported, this is just an error, which
+ // sema should catch, but...
+ ErrorUnsupported(D, "alias referencing a missing function");
+ continue;
+ }
+
+ llvm::GlobalValue *GA =
+ new llvm::GlobalAlias(aliasee->getType(),
+ llvm::Function::ExternalLinkage,
+ D->getName(),
+ aliasee,
+ &getModule());
+
+ llvm::GlobalValue *&Entry = GlobalDeclMap[D->getIdentifier()];
+ if (Entry) {
+ // If we created a dummy function for this then replace it.
+ GA->takeName(Entry);
+
+ llvm::Value *Casted =
+ llvm::ConstantExpr::getBitCast(GA, Entry->getType());
+ Entry->replaceAllUsesWith(Casted);
+ Entry->eraseFromParent();
+
+ Entry = GA;
+ }
- SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static,
- FD->isInline(), F);
+ // Alias should never be internal or inline.
+ SetGlobalValueAttributes(D, false, false, GA, true);
+ }
}
void CodeGenModule::EmitStatics() {
@@ -250,6 +314,8 @@
// Check if we have used a decl with the same name
// FIXME: The AST should have some sort of aggregate decls or
// global symbol map.
+ // FIXME: This is missing some important cases. For example, we
+ // need to check for uses in an alias and in a constructor.
if (!GlobalDeclMap.count(D->getIdentifier()))
continue;
@@ -316,8 +382,16 @@
bool isDef, isStatic;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
- isDef = (FD->isThisDeclarationADefinition() ||
- FD->getAttr<AliasAttr>());
+ // Aliases are deferred until code for everything else has been
+ // emitted.
+ if (FD->getAttr<AliasAttr>()) {
+ assert(!FD->isThisDeclarationADefinition() &&
+ "Function alias cannot have a definition!");
+ Aliases.push_back(FD);
+ return;
+ }
+
+ isDef = FD->isThisDeclarationADefinition();
isStatic = FD->getStorageClass() == FunctionDecl::Static;
} else if (const VarDecl *VD = cast<VarDecl>(Global)) {
assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
@@ -512,29 +586,12 @@
llvm::GlobalValue *
CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D) {
- // FIXME: param attributes for sext/zext etc.
- if (const AliasAttr *AA = D->getAttr<AliasAttr>()) {
- assert(!D->getBody() && "Unexpected alias attr on function with body.");
-
- const std::string& aliaseeName = AA->getAliasee();
- llvm::Function *aliasee = getModule().getFunction(aliaseeName);
- llvm::GlobalValue *alias = new llvm::GlobalAlias(aliasee->getType(),
- llvm::Function::ExternalLinkage,
- D->getName(),
- aliasee,
- &getModule());
- // Alias should never be internal
- SetGlobalValueAttributes(D, false, false, alias);
- return alias;
- } else {
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
- llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
- llvm::Function::ExternalLinkage,
- D->getName(), &getModule());
-
- SetFunctionAttributes(D, F);
- return F;
- }
+ const llvm::Type *Ty = getTypes().ConvertType(D->getType());
+ llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
+ llvm::Function::ExternalLinkage,
+ D->getName(), &getModule());
+ SetFunctionAttributes(D, F);
+ return F;
}
llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D) {
@@ -575,33 +632,22 @@
Entry->replaceAllUsesWith(NewPtrForOldDecl);
// Ok, delete the old function now, which is dead.
- // FIXME: Add GlobalValue->eraseFromParent().
assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
- if (llvm::Function *F = dyn_cast<llvm::Function>(Entry)) {
- F->eraseFromParent();
- } else if (llvm::GlobalAlias *GA = dyn_cast<llvm::GlobalAlias>(Entry)) {
- GA->eraseFromParent();
- } else {
- assert(0 && "Invalid global variable type.");
- }
+ Entry->eraseFromParent();
Entry = NewFn;
}
}
- if (D->getAttr<AliasAttr>()) {
- ;
- } else {
- llvm::Function *Fn = cast<llvm::Function>(Entry);
- CodeGenFunction(*this).GenerateCode(D, Fn);
-
- SetFunctionAttributesForDefinition(Fn);
+ llvm::Function *Fn = cast<llvm::Function>(Entry);
+ CodeGenFunction(*this).GenerateCode(D, Fn);
- if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) {
- AddGlobalCtor(Fn, CA->getPriority());
- } else if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) {
- AddGlobalDtor(Fn, DA->getPriority());
- }
+ SetFunctionAttributesForDefinition(D, Fn);
+
+ if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) {
+ AddGlobalCtor(Fn, CA->getPriority());
+ } else if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) {
+ AddGlobalDtor(Fn, DA->getPriority());
}
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=55966&r1=55965&r2=55966&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Sep 8 18:44:31 2008
@@ -79,11 +79,16 @@
/// (which may change with attributes such as asm-labels).
llvm::DenseMap<IdentifierInfo*, llvm::GlobalValue*> GlobalDeclMap;
- /// List of static global for which code generation is delayed. When
- /// the translation unit has been fully processed we will lazily
- /// emit definitions for only the decls that were actually used.
- /// This should contain only Function and Var decls, and only those
- /// which actually define something.
+ /// Aliases - List of aliases in module. These cannot be emitted
+ /// until all the code has been seen, as they reference things by
+ /// name instead of directly and may reference forward.
+ std::vector<const FunctionDecl*> Aliases;
+
+ /// StaticDecls - List of static global for which code generation is
+ /// delayed. When the translation unit has been fully processed we
+ /// will lazily emit definitions for only the decls that were
+ /// actually used. This should contain only Function and Var decls,
+ /// and only those which actually define something.
std::vector<const ValueDecl*> StaticDecls;
/// GlobalCtors - Store the list of global constructors and their
@@ -213,7 +218,9 @@
private:
/// SetFunctionAttributesForDefinition - Set function attributes
/// specific to a function definition.
- void SetFunctionAttributesForDefinition(llvm::Function *F);
+ /// \param D - The ObjCMethodDecl or FunctionDecl defining \arg F.
+ void SetFunctionAttributesForDefinition(const Decl *D,
+ llvm::Function *F);
void SetFunctionAttributes(const FunctionDecl *FD,
llvm::Function *F);
@@ -238,9 +245,9 @@
/// or destructor array.
void EmitCtorList(const CtorList &Fns, const char *GlobalName);
+ void EmitAliases(void);
void EmitAnnotations(void);
void EmitStatics(void);
-
};
} // end namespace CodeGen
} // end namespace clang
Added: cfe/trunk/test/CodeGen/PR2743-reference-missing-static.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/PR2743-reference-missing-static.c?rev=55966&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/PR2743-reference-missing-static.c (added)
+++ cfe/trunk/test/CodeGen/PR2743-reference-missing-static.c Mon Sep 8 18:44:31 2008
@@ -0,0 +1,16 @@
+// RUN: clang -emit-llvm -o %t %s
+// PR2743
+// <rdr://6094512>
+
+/* CodeGen should handle this even if it makes it past
+ sema. Unfortunately this test will become useless once sema starts
+ rejecting this. */
+
+static void e0();
+void f0() { e0(); }
+
+inline void e1();
+void f1() { e1(); }
+
+void e2() __attribute__((weak));
+void f2() { e2(); }
Added: cfe/trunk/test/CodeGen/rdr-6095112-alias-references-inline.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/rdr-6095112-alias-references-inline.c?rev=55966&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/rdr-6095112-alias-references-inline.c (added)
+++ cfe/trunk/test/CodeGen/rdr-6095112-alias-references-inline.c Mon Sep 8 18:44:31 2008
@@ -0,0 +1,6 @@
+// RUN: clang --emit-llvm -o %t %s &&
+// RUN: grep -e "alias" %t
+// XFAIL
+
+static inline int foo () { return 0; }
+int bar () __attribute__ ((alias ("foo")));
Added: cfe/trunk/test/CodeGen/rdr-6140807-alias-references-forward.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/rdr-6140807-alias-references-forward.c?rev=55966&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/rdr-6140807-alias-references-forward.c (added)
+++ cfe/trunk/test/CodeGen/rdr-6140807-alias-references-forward.c Mon Sep 8 18:44:31 2008
@@ -0,0 +1,14 @@
+// RUN: clang -emit-llvm -o %t %s &&
+// RUN: grep -e "@f = alias" %t | count 1 &&
+// RUN: grep -e "bitcast (i32 (i32)\\* @f to i32 (float)\\*)" %t | count 1
+// <rdar://problem/6140807>
+
+int f(float) __attribute__((weak, alias("x")));
+
+// Make sure we replace uses properly...
+int y() {
+ return f(1.);
+}
+
+int x(int) {
+}
More information about the cfe-commits
mailing list