summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2011-12-19 14:41:01 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2011-12-19 14:41:01 +0000
commitbcf6b98247bd3ac76c5edf706b1087a8d32c0320 (patch)
treea4b32cdcca2ce5f479c482e1f3ea20c5675f55d6 /lib/CodeGen/CodeGenModule.cpp
parent0f45682b463773896c9e40ee1ed2b3e4ade1561e (diff)
Extend the fix for PR9614 to handle inline asm in the outer decl and
the inner decl being a builtin. This is needed to support the glibc headers in fedora 16 (2.14). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146867 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp47
1 files changed, 32 insertions, 15 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 0e8468f31d..16d01efb93 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -30,6 +30,7 @@
#include "clang/AST/Mangle.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -863,20 +864,27 @@ namespace {
struct FunctionIsDirectlyRecursive :
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
const StringRef Name;
+ const Builtin::Context &BI;
bool Result;
- FunctionIsDirectlyRecursive(const FunctionDecl *F) :
- Name(F->getName()), Result(false) {
+ FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) :
+ Name(N), BI(C), Result(false) {
}
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
bool TraverseCallExpr(CallExpr *E) {
- const Decl *D = E->getCalleeDecl();
- if (!D)
+ const FunctionDecl *FD = E->getDirectCallee();
+ if (!FD)
return true;
- AsmLabelAttr *Attr = D->getAttr<AsmLabelAttr>();
- if (!Attr)
+ AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
+ if (Attr && Name == Attr->getLabel()) {
+ Result = true;
+ return false;
+ }
+ unsigned BuiltinID = FD->getBuiltinID();
+ if (!BuiltinID)
return true;
- if (Name == Attr->getLabel()) {
+ const char *BuiltinName = BI.GetName(BuiltinID) + strlen("__builtin_");
+ if (Name == BuiltinName) {
Result = true;
return false;
}
@@ -885,15 +893,24 @@ namespace {
};
}
-// isTriviallyRecursiveViaAsm - Check if this function calls another
-// decl that, because of the asm attribute, ends up pointing to itself.
+// isTriviallyRecursive - Check if this function calls another
+// decl that, because of the asm attribute or the other decl being a builtin,
+// ends up pointing to itself.
bool
-CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) {
- if (getCXXABI().getMangleContext().shouldMangleDeclName(F))
- return false;
+CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
+ StringRef Name;
+ if (getCXXABI().getMangleContext().shouldMangleDeclName(FD)) {
+ // asm labels are a special king of mangling we have to support.
+ AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
+ if (!Attr)
+ return false;
+ Name = Attr->getLabel();
+ } else {
+ Name = FD->getName();
+ }
- FunctionIsDirectlyRecursive Walker(F);
- Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
+ FunctionIsDirectlyRecursive Walker(Name, Context.BuiltinInfo);
+ Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(FD));
return Walker.Result;
}
@@ -909,7 +926,7 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
// but a function that calls itself is clearly not equivalent to the real
// implementation.
// This happens in glibc's btowc and in some configure checks.
- return !isTriviallyRecursiveViaAsm(F);
+ return !isTriviallyRecursive(F);
}
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {