30
30
#include " clang/AST/Mangle.h"
31
31
#include " clang/AST/RecordLayout.h"
32
32
#include " clang/AST/RecursiveASTVisitor.h"
33
+ #include " clang/Basic/Builtins.h"
33
34
#include " clang/Basic/Diagnostic.h"
34
35
#include " clang/Basic/SourceManager.h"
35
36
#include " clang/Basic/TargetInfo.h"
@@ -863,20 +864,27 @@ namespace {
863
864
struct FunctionIsDirectlyRecursive :
864
865
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
865
866
const StringRef Name;
867
+ const Builtin::Context &BI;
866
868
bool Result;
867
- FunctionIsDirectlyRecursive (const FunctionDecl *F ) :
868
- Name (F-> getName () ), Result(false ) {
869
+ FunctionIsDirectlyRecursive (StringRef N, const Builtin::Context &C ) :
870
+ Name (N), BI(C ), Result(false ) {
869
871
}
870
872
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
871
873
872
874
bool TraverseCallExpr (CallExpr *E) {
873
- const Decl *D = E->getCalleeDecl ();
874
- if (!D )
875
+ const FunctionDecl *FD = E->getDirectCallee ();
876
+ if (!FD )
875
877
return true ;
876
- AsmLabelAttr *Attr = D->getAttr <AsmLabelAttr>();
877
- if (!Attr)
878
+ AsmLabelAttr *Attr = FD->getAttr <AsmLabelAttr>();
879
+ if (Attr && Name == Attr->getLabel ()) {
880
+ Result = true ;
881
+ return false ;
882
+ }
883
+ unsigned BuiltinID = FD->getBuiltinID ();
884
+ if (!BuiltinID)
878
885
return true ;
879
- if (Name == Attr->getLabel ()) {
886
+ const char *BuiltinName = BI.GetName (BuiltinID) + strlen (" __builtin_" );
887
+ if (Name == BuiltinName) {
880
888
Result = true ;
881
889
return false ;
882
890
}
@@ -885,15 +893,24 @@ namespace {
885
893
};
886
894
}
887
895
888
- // isTriviallyRecursiveViaAsm - Check if this function calls another
889
- // decl that, because of the asm attribute, ends up pointing to itself.
896
+ // isTriviallyRecursive - Check if this function calls another
897
+ // decl that, because of the asm attribute or the other decl being a builtin,
898
+ // ends up pointing to itself.
890
899
bool
891
- CodeGenModule::isTriviallyRecursiveViaAsm (const FunctionDecl *F) {
892
- if (getCXXABI ().getMangleContext ().shouldMangleDeclName (F))
893
- return false ;
900
+ CodeGenModule::isTriviallyRecursive (const FunctionDecl *FD) {
901
+ StringRef Name;
902
+ if (getCXXABI ().getMangleContext ().shouldMangleDeclName (FD)) {
903
+ // asm labels are a special king of mangling we have to support.
904
+ AsmLabelAttr *Attr = FD->getAttr <AsmLabelAttr>();
905
+ if (!Attr)
906
+ return false ;
907
+ Name = Attr->getLabel ();
908
+ } else {
909
+ Name = FD->getName ();
910
+ }
894
911
895
- FunctionIsDirectlyRecursive Walker (F );
896
- Walker.TraverseFunctionDecl (const_cast <FunctionDecl*>(F ));
912
+ FunctionIsDirectlyRecursive Walker (Name, Context. BuiltinInfo );
913
+ Walker.TraverseFunctionDecl (const_cast <FunctionDecl*>(FD ));
897
914
return Walker.Result ;
898
915
}
899
916
@@ -909,7 +926,7 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
909
926
// but a function that calls itself is clearly not equivalent to the real
910
927
// implementation.
911
928
// This happens in glibc's btowc and in some configure checks.
912
- return !isTriviallyRecursiveViaAsm (F);
929
+ return !isTriviallyRecursive (F);
913
930
}
914
931
915
932
void CodeGenModule::EmitGlobalDefinition (GlobalDecl GD) {
0 commit comments