diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -663,10 +663,9 @@ unsigned LineNo, StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext); - - /// Return flags which enable debug info emission for call sites, provided + /// Return SPFlags which enable debug info emission for call sites, provided /// that it is supported and enabled. - llvm::DINode::DIFlags getCallSiteRelatedAttrs() const; + llvm::DISubprogram::DISPFlags getCallSiteRelatedAttrs() const; /// Get the printing policy for producing names for debug info. PrintingPolicy getPrintingPolicy() const; @@ -711,7 +710,7 @@ StringRef &Name, StringRef &LinkageName, llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray, - llvm::DINode::DIFlags &Flags); + llvm::DISubprogram::DISPFlags &SPFlags); /// Collect various properties of a VarDecl. void collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit, diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1639,7 +1639,7 @@ } if (Method->isNoReturn()) - Flags |= llvm::DINode::FlagNoReturn; + SPFlags |= llvm::DISubprogram::SPFlagNoReturn; if (Method->isStatic()) Flags |= llvm::DINode::FlagStaticMember; @@ -1648,13 +1648,13 @@ Flags |= getAccessFlag(Method->getAccess(), Method->getParent()); if (const auto *CXXC = dyn_cast(Method)) { if (CXXC->isExplicit()) - Flags |= llvm::DINode::FlagExplicit; + SPFlags |= llvm::DISubprogram::SPFlagExplicit; } else if (const auto *CXXC = dyn_cast(Method)) { if (CXXC->isExplicit()) - Flags |= llvm::DINode::FlagExplicit; + SPFlags |= llvm::DISubprogram::SPFlagExplicit; } if (Method->hasPrototype()) - Flags |= llvm::DINode::FlagPrototyped; + SPFlags |= llvm::DISubprogram::SPFlagPrototyped; if (Method->getRefQualifier() == RQ_LValue) Flags |= llvm::DINode::FlagLValueReference; if (Method->getRefQualifier() == RQ_RValue) @@ -3280,18 +3280,16 @@ return Ty; } -void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit, - StringRef &Name, - StringRef &LinkageName, - llvm::DIScope *&FDContext, - llvm::DINodeArray &TParamsArray, - llvm::DINode::DIFlags &Flags) { +void CGDebugInfo::collectFunctionDeclProps( + GlobalDecl GD, llvm::DIFile *Unit, StringRef &Name, StringRef &LinkageName, + llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray, + llvm::DISubprogram::DISPFlags &SPFlags) { const auto *FD = cast(GD.getDecl()); Name = getFunctionName(FD); // Use mangled name as linkage name for C/C++ functions. if (FD->hasPrototype()) { LinkageName = CGM.getMangledName(GD); - Flags |= llvm::DINode::FlagPrototyped; + SPFlags |= llvm::DISubprogram::SPFlagPrototyped; } // No need to replicate the linkage name if it isn't different from the // subprogram name, no need to have it at all unless coverage is enabled or @@ -3313,7 +3311,7 @@ } // Check if it is a noreturn-marked function if (FD->isNoReturn()) - Flags |= llvm::DINode::FlagNoReturn; + SPFlags |= llvm::DISubprogram::SPFlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } @@ -3385,7 +3383,7 @@ llvm::DIScope *DContext = Unit; unsigned Line = getLineNumber(Loc); collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray, - Flags); + SPFlags); auto *FD = cast(GD.getDecl()); // Build function type. @@ -3402,7 +3400,7 @@ SPFlags |= llvm::DISubprogram::SPFlagOptimized; if (Stub) { - Flags |= getCallSiteRelatedAttrs(); + SPFlags |= getCallSiteRelatedAttrs(); SPFlags |= llvm::DISubprogram::SPFlagDefinition; return DBuilder.createFunction( DContext, Name, LinkageName, Unit, Line, @@ -3655,10 +3653,10 @@ } } collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext, - TParamsArray, Flags); + TParamsArray, SPFlags); } else if (const auto *OMD = dyn_cast(D)) { Name = getObjCMethodName(OMD); - Flags |= llvm::DINode::FlagPrototyped; + SPFlags |= llvm::DISubprogram::SPFlagPrototyped; } else if (isa(D) && GD.getDynamicInitKind() != DynamicInitKind::NoStub) { // This is a global initializer or atexit destructor for a global variable. @@ -3670,7 +3668,7 @@ if (isa(D)) LinkageName = Name; - Flags |= llvm::DINode::FlagPrototyped; + SPFlags |= llvm::DISubprogram::SPFlagPrototyped; } if (Name.startswith("\01")) Name = Name.substr(1); @@ -3682,16 +3680,17 @@ } if (CurFuncIsThunk) - Flags |= llvm::DINode::FlagThunk; + SPFlags |= llvm::DISubprogram::SPFlagThunk; if (Fn->hasLocalLinkage()) SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit; if (CGM.getLangOpts().Optimize) SPFlags |= llvm::DISubprogram::SPFlagOptimized; - llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs(); + llvm::DINode::DIFlags FlagsForDef = Flags; llvm::DISubprogram::DISPFlags SPFlagsForDef = - SPFlags | llvm::DISubprogram::SPFlagDefinition; + SPFlags | llvm::DISubprogram::SPFlagDefinition | + getCallSiteRelatedAttrs(); unsigned LineNo = getLineNumber(Loc); unsigned ScopeLine = getLineNumber(ScopeLoc); @@ -3748,13 +3747,14 @@ llvm::DIScope *FDContext = IsDeclForCallSite ? Unit : getDeclContextDescriptor(D); llvm::DINodeArray TParamsArray; + llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; if (isa(D)) { // If there is a DISubprogram for this function available then use it. collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext, - TParamsArray, Flags); + TParamsArray, SPFlags); } else if (const auto *OMD = dyn_cast(D)) { Name = getObjCMethodName(OMD); - Flags |= llvm::DINode::FlagPrototyped; + SPFlags |= llvm::DISubprogram::SPFlagPrototyped; } else { llvm_unreachable("not a function or ObjC method"); } @@ -3769,7 +3769,6 @@ } unsigned LineNo = getLineNumber(Loc); unsigned ScopeLine = 0; - llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; if (CGM.getLangOpts().Optimize) SPFlags |= llvm::DISubprogram::SPFlagOptimized; @@ -3801,7 +3800,7 @@ // compiler may emit calls to these functions without debug locations, which // makes the verifier complain). if (CalleeDecl->getBuiltinID() != 0 || - getCallSiteRelatedAttrs() == llvm::DINode::FlagZero) + getCallSiteRelatedAttrs() == llvm::DISubprogram::SPFlagZero) return; if (const auto *Id = CalleeDecl->getIdentifier()) if (Id->isReservedName()) @@ -4846,12 +4845,12 @@ return llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc), Scope); } -llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { +llvm::DISubprogram::DISPFlags CGDebugInfo::getCallSiteRelatedAttrs() const { // Call site-related attributes are only useful in optimized programs, and // when there's a possibility of debugging backtraces. if (!CGM.getLangOpts().Optimize || DebugKind == codegenoptions::NoDebugInfo || DebugKind == codegenoptions::LocTrackingOnly) - return llvm::DINode::FlagZero; + return llvm::DISubprogram::SPFlagZero; // Call site-related attributes are available in DWARF v5. Some debuggers, // while not fully DWARF v5-compliant, may accept these attributes as if they @@ -4862,7 +4861,7 @@ CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB); if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5) - return llvm::DINode::FlagZero; + return llvm::DISubprogram::SPFlagZero; - return llvm::DINode::FlagAllCallsDescribed; + return llvm::DISubprogram::SPFlagAllCallsDescribed; } diff --git a/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp b/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp --- a/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp +++ b/clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp @@ -5,7 +5,7 @@ // RUN: -O1 -disable-llvm-passes \ // RUN: -debug-info-kind=standalone -dwarf-version=5 \ // RUN: | FileCheck %s -check-prefix=HAS-ATTR \ -// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed +// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DISPFlagAllCallsDescribed // Supported: DWARF4 + LLDB tuning, -O1, limited DI // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \ @@ -13,7 +13,7 @@ // RUN: -debugger-tuning=lldb \ // RUN: -debug-info-kind=standalone -dwarf-version=4 \ // RUN: | FileCheck %s -check-prefix=HAS-ATTR \ -// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed +// RUN: -implicit-check-not=DISubprogram -implicit-check-not=DISPFlagAllCallsDescribed // Supported: DWARF4 + GDB tuning, -O1 // RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu \ @@ -56,14 +56,14 @@ // NO-ATTR-NOT: FlagAllCallsDescribed -// HAS-ATTR-DAG: DISubprogram(name: "declaration1", {{.*}}, flags: DIFlagPrototyped -// HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition -// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) -// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition -// HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition -// HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition +// HAS-ATTR-DAG: DISubprogram(name: "declaration1", {{.*}}, spFlags: DISPFlagOptimized | DISPFlagPrototyped +// HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed +// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, spFlags: DISPFlagOptimized | DISPFlagPrototyped) +// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed +// HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed +// HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed -// LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition +// LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed void declaration1(); diff --git a/clang/test/CodeGenCXX/debug-info-access.cpp b/clang/test/CodeGenCXX/debug-info-access.cpp --- a/clang/test/CodeGenCXX/debug-info-access.cpp +++ b/clang/test/CodeGenCXX/debug-info-access.cpp @@ -3,7 +3,7 @@ struct A { // CHECK: ![[A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", - // CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, + // CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} spFlags: DISPFlagPrototyped void pub_default(); // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "pub_default_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagStaticMember) static int pub_default_static; @@ -13,30 +13,28 @@ // CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: ![[A]],{{.*}} flags: DIFlagPublic, extraData: i32 0) class B : public A { public: - // CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagPrototyped, + // CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic,{{.*}}spFlags: DISPFlagPrototyped void pub(); // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "public_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagStaticMember) static int public_static; protected: - // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected | DIFlagPrototyped, + // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected,{{.*}}spFlags: DISPFlagPrototyped void prot(); private: - // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, + // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} spFlags: DISPFlagPrototyped void priv_default(); }; union U { - // CHECK-DAG: !DISubprogram(name: "union_pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, + // CHECK-DAG: !DISubprogram(name: "union_pub_default",{{.*}} line: [[@LINE+1]],{{.*}} spFlags: DISPFlagPrototyped void union_pub_default(); private: // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "union_priv",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrivate) int union_priv; }; - // CHECK: !DISubprogram(name: "free", -// CHECK-SAME: flags: DIFlagPrototyped, -// CHECK-SAME: spFlags: DISPFlagDefinition +// CHECK-SAME: spFlags: DISPFlagDefinition | DISPFlagPrototyped void free() {} U u; diff --git a/clang/test/CodeGenCXX/debug-info-cxx1y.cpp b/clang/test/CodeGenCXX/debug-info-cxx1y.cpp --- a/clang/test/CodeGenCXX/debug-info-cxx1y.cpp +++ b/clang/test/CodeGenCXX/debug-info-cxx1y.cpp @@ -23,7 +23,7 @@ // CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func", // CHECK-SAME: scope: [[FOO]] // CHECK-SAME: type: [[SUBROUTINE_TYPE]] -// CHECK-SAME: spFlags: 0 +// CHECK-SAME: spFlags: DISPFlagPrototyped) struct foo { static auto func(); diff --git a/clang/test/CodeGenCXX/debug-info-decl-nested.cpp b/clang/test/CodeGenCXX/debug-info-decl-nested.cpp --- a/clang/test/CodeGenCXX/debug-info-decl-nested.cpp +++ b/clang/test/CodeGenCXX/debug-info-decl-nested.cpp @@ -17,9 +17,9 @@ public: InnerClass(); // Here createContextChain() generates a limited type for OuterClass. } theInnerClass; -// CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass" -// CHECK0-SAME: line: [[@LINE+2]] -// CHECK0-SAME: spFlags: 0 + // CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass" + // CHECK0-SAME: line: [[@LINE+2]] + // CHECK0-SAME: spFlags: DISPFlagPrototyped OuterClass(const Foo *); // line 10 }; OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated. @@ -41,9 +41,9 @@ public: InnerClass1(); } theInnerClass1; -// CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar" -// CHECK1-SAME: line: [[@LINE+2]] -// CHECK1-SAME: spFlags: 0 + // CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar" + // CHECK1-SAME: line: [[@LINE+2]] + // CHECK1-SAME: spFlags: DISPFlagPrototyped void Bar(const Foo1 *); }; OuterClass1::InnerClass1 OuterClass1::theInnerClass1; @@ -64,9 +64,9 @@ public: InnerClass2(); } theInnerClass2; -// CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2" -// CHECK2-SAME: line: [[@LINE+2]] -// CHECK2-SAME: spFlags: 0 + // CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2" + // CHECK2-SAME: line: [[@LINE+2]] + // CHECK2-SAME: spFlags: DISPFlagPrototyped ~OuterClass2(); // line 10 }; OuterClass2::InnerClass2 OuterClass2::theInnerClass2; diff --git a/clang/test/CodeGenCXX/debug-info-deleted.cpp b/clang/test/CodeGenCXX/debug-info-deleted.cpp --- a/clang/test/CodeGenCXX/debug-info-deleted.cpp +++ b/clang/test/CodeGenCXX/debug-info-deleted.cpp @@ -6,12 +6,12 @@ // RUN: -debug-info-kind=standalone \ // RUN: | FileCheck %s -check-prefix=ATTR -// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, -// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted -// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSERKS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted -// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted -// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted -// ATTR: DISubprogram(name: "~deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, +// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagPrototyped +// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped +// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSERKS_", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped +// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped +// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSEOS_", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped +// ATTR: DISubprogram(name: "~deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagPrototyped class deleted { public: // Defaulted on purpose, so as to facilitate object creation diff --git a/clang/test/CodeGenCXX/debug-info-ms-abi.cpp b/clang/test/CodeGenCXX/debug-info-ms-abi.cpp --- a/clang/test/CodeGenCXX/debug-info-ms-abi.cpp +++ b/clang/test/CodeGenCXX/debug-info-ms-abi.cpp @@ -31,21 +31,22 @@ // CHECK: ![[f]] = !DISubprogram(name: "f", // CHECK-SAME: containingType: ![[Foo]], virtualIndex: 0, -// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual, -// CHECK-SAME: spFlags: DISPFlagVirtual +// CHECK-SAME: flags: DIFlagIntroducedVirtual, +// CHECK-SAME: spFlags: DISPFlagVirtual | DISPFlagPrototyped // CHECK: ![[g]] = !DISubprogram(name: "g", // CHECK-SAME: containingType: ![[Foo]], virtualIndex: 1, -// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual, -// CHECK-SAME: spFlags: DISPFlagVirtual +// CHECK-SAME: flags: DIFlagIntroducedVirtual, +// CHECK-SAME: spFlags: DISPFlagVirtual | DISPFlagPrototyped // CHECK: ![[h]] = !DISubprogram(name: "h", // CHECK-SAME: containingType: ![[Foo]], virtualIndex: 2, -// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual, -// CHECK-SAME: spFlags: DISPFlagVirtual +// CHECK-SAME: flags: DIFlagIntroducedVirtual, +// CHECK-SAME: spFlags: DISPFlagVirtual | DISPFlagPrototyped // CHECK: ![[i]] = !DISubprogram(name: "i", -// CHECK-SAME: flags: DIFlagPrototyped | DIFlagStaticMember +// CHECK-SAME: flags: DIFlagStaticMember +// CHECK-SAME: spFlags: DISPFlagPrototyped // CHECK-NEXT: ![[dummy:[0-9]+]] = !DISubroutineType(types: ![[Signature:[0-9]+]]) // CHECK: ![[Signature]] = !{null, ![[BasicInt:[0-9]+]], ![[BasicInt]]} // CHECK: ![[BasicInt]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) diff --git a/clang/test/CodeGenCXX/debug-info-noreturn.cpp b/clang/test/CodeGenCXX/debug-info-noreturn.cpp --- a/clang/test/CodeGenCXX/debug-info-noreturn.cpp +++ b/clang/test/CodeGenCXX/debug-info-noreturn.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -emit-llvm -fcxx-exceptions -debug-info-kind=standalone %s -o - | FileCheck %s // Test for NoReturn flags in debug info. -// CHECK: DISubprogram(name: "f", {{.*}}, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagDefinition -// CHECK: DISubprogram(name: "foo_member", {{.*}}, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: 0 -// CHECK-NOT: DISubprogram(name: "func",{{.*}}, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagDefinition +// CHECK: DISubprogram(name: "f", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagPrototyped | DISPFlagNoReturn, +// CHECK: DISubprogram(name: "foo_member", {{.*}}, spFlags: DISPFlagPrototyped | DISPFlagNoReturn) +// CHECK-NOT: DISubprogram(name: "func",{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPrototyped | DISPFlagNoReturn class foo { diff --git a/clang/test/CodeGenCXX/debug-info-qualifiers.cpp b/clang/test/CodeGenCXX/debug-info-qualifiers.cpp --- a/clang/test/CodeGenCXX/debug-info-qualifiers.cpp +++ b/clang/test/CodeGenCXX/debug-info-qualifiers.cpp @@ -3,18 +3,20 @@ class A { public: // CHECK: !DISubprogram(name: "l", - // CHECK-SAME: line: [[@LINE+4]] + // CHECK-SAME: line: [[@LINE+5]] // CHECK-SAME: type: ![[PLSR:[0-9]+]] - // CHECK-SAME: flags: DIFlagPublic | DIFlagPrototyped | DIFlagLValueReference, + // CHECK-SAME: flags: DIFlagPublic | DIFlagLValueReference, + // CHECK-SAME: spFlags: DISPFlagPrototyped) // CHECK: ![[PLSR]] = !DISubroutineType(flags: DIFlagLValueReference, types: ![[ARGS:[0-9]+]]) void l() const &; // CHECK: ![[ARGS]] = !{null, ![[THIS:[0-9]+]]} // CHECK: ![[THIS]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[CONST_A:[0-9]+]] // CHECK: ![[CONST_A]] = !DIDerivedType(tag: DW_TAG_const_type // CHECK: !DISubprogram(name: "r" - // CHECK-SAME: line: [[@LINE+4]] + // CHECK-SAME: line: [[@LINE+5]] // CHECK-SAME: type: ![[PRSR:[0-9]+]] - // CHECK-SAME: flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference, + // CHECK-SAME: flags: DIFlagPublic | DIFlagRValueReference, + // CHECK-SAME: spFlags: DISPFlagPrototyped) // CHECK: ![[PRSR]] = !DISubroutineType(flags: DIFlagRValueReference, types: ![[ARGS]]) void r() const &&; }; diff --git a/clang/test/CodeGenCXX/debug-info-thunk.cpp b/clang/test/CodeGenCXX/debug-info-thunk.cpp --- a/clang/test/CodeGenCXX/debug-info-thunk.cpp +++ b/clang/test/CodeGenCXX/debug-info-thunk.cpp @@ -28,8 +28,8 @@ virtual void f(); }; - -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test1@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk + + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test1@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk void C::f() { } } @@ -46,8 +46,8 @@ virtual V2 *f(); }; - -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@B@Test2@@QEAAPEAUV1@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk + + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@B@Test2@@QEAAPEAUV1@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk V2 *B::f() { return 0; } } @@ -65,8 +65,8 @@ virtual void f(); }; - -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test3@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk + + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test3@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk void C::f() { } } @@ -86,7 +86,7 @@ }; } void C::c() {} -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk void C::f() {} // Force C::f to be used. @@ -132,7 +132,7 @@ virtual X f(); }; -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@Thunks@Test5@@WBA@EAA?AUX@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@Thunks@Test5@@WBA@EAA?AUX@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk X Thunks::f() { return X(); } } @@ -166,7 +166,7 @@ class D : public B, public C { -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@D@Test6@@G7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@D@Test6@@G7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk void foo() {} void bar() {} void baz(X, X&, _Complex float, Small, Small&, Large); @@ -180,7 +180,7 @@ namespace Test7 { struct A { virtual void foo(); }; struct B { virtual void foo(); }; -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@C@Test7@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@C@Test7@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk struct C : A, B { void foo() {} }; // Test later. @@ -193,7 +193,7 @@ struct A { virtual A* f(); }; struct B : virtual A { virtual A* f(); }; struct C : B { virtual C* f(); }; -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test8@@QEAAPEAUA@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test8@@QEAAPEAUA@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk C* C::f() { return 0; } } @@ -211,8 +211,8 @@ virtual ~D(); virtual D &foo1(); }; -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAUB1@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAU12@XZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAUB1@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAU12@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk D& D::foo1() { return *this; } @@ -228,7 +228,7 @@ class C : public A, public B { virtual void f(); }; -// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test10@@G7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test10@@G7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk void C::f() { } } @@ -240,7 +240,7 @@ }; void test() { -// CHECK-DAG: DISubprogram{{.*}}linkageName: "??_9A@Test11@@$BA@AA"{{.*}} flags: {{.*}}DIFlagThunk + // CHECK-DAG: DISubprogram{{.*}}linkageName: "??_9A@Test11@@$BA@AA"{{.*}} spFlags: {{.*}}DISPFlagThunk void (A::*p)() = &A::f; } } @@ -269,8 +269,8 @@ // ITANIUM: ![[SP]] = distinct !DISubprogram(linkageName: "_ZThn{{[48]}}_N6Test121C1fEv" // ITANIUM-SAME: line: 261 // ITANIUM-SAME: DIFlagArtificial - // ITANIUM-SAME: DIFlagThunk // ITANIUM-SAME: DISPFlagDefinition + // ITANIUM-SAME: DISPFlagThunk // ITANIUM-SAME: ){{$}} // // ITANIUM: ![[DBG]] = !DILocation(line: 0 diff --git a/clang/test/CodeGenObjC/debug-info-category.m b/clang/test/CodeGenObjC/debug-info-category.m --- a/clang/test/CodeGenObjC/debug-info-category.m +++ b/clang/test/CodeGenObjC/debug-info-category.m @@ -37,15 +37,15 @@ // CHECK: ![[STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" // Verify "not a definition" by showing spFlags doesn't have DISPFlagDefinition. -// DWARF5: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, -// DWARF5: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, -// DWARF5: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, -// DWARF5: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, - -// DWARF4-NOT: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, -// DWARF4-NOT: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, -// DWARF4-NOT: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, -// DWARF4-NOT: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit, +// DWARF5: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, +// DWARF5: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, +// DWARF5: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, +// DWARF5: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, + +// DWARF4-NOT: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, +// DWARF4-NOT: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, +// DWARF4-NOT: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, +// DWARF4-NOT: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped, // CHECK: = distinct !DISubprogram(name: "-[Foo integer]"{{.*}} DISPFlagDefinition // CHECK: = distinct !DISubprogram(name: "-[Foo integer:]"{{.*}} DISPFlagDefinition diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -192,9 +192,9 @@ /// \param SizeInBits Size of the type. /// \param Encoding DWARF encoding code, e.g., dwarf::DW_ATE_float. /// \param Flags Optional DWARF attributes, e.g., DW_AT_endianity. - DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits, - unsigned Encoding, - DINode::DIFlags Flags = DINode::FlagZero); + DIBasicType * + createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, + DIBasicType::DIBTFlags Flags = DIBasicType::BTFlagZero); /// Create debugging information entry for a qualified /// type, e.g. 'const int'. diff --git a/llvm/include/llvm/IR/DebugInfoFlags.def b/llvm/include/llvm/IR/DebugInfoFlags.def --- a/llvm/include/llvm/IR/DebugInfoFlags.def +++ b/llvm/include/llvm/IR/DebugInfoFlags.def @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -#if !(defined HANDLE_DI_FLAG || defined HANDLE_DISP_FLAG) +#if !(defined HANDLE_DI_FLAG || defined HANDLE_DISP_FLAG || \ + defined HANDLE_DIBT_FLAG || defined HANDLE_DIVAR_FLAG) #error "Missing macro definition of HANDLE_DI*" #endif @@ -22,6 +23,14 @@ #define HANDLE_DISP_FLAG(ID, NAME) #endif +#ifndef HANDLE_DIBT_FLAG +#define HANDLE_DIBT_FLAG(ID, NAME) +#endif + +#ifndef HANDLE_DIVAR_FLAG +#define HANDLE_DIVAR_FLAG(ID, NAME) +#endif + // General flags kept in DINode. HANDLE_DI_FLAG(0, Zero) // Use it as zero value. @@ -55,8 +64,6 @@ HANDLE_DI_FLAG((1 << 24), EnumClass) HANDLE_DI_FLAG((1 << 25), Thunk) HANDLE_DI_FLAG((1 << 26), NonTrivial) -HANDLE_DI_FLAG((1 << 27), BigEndian) -HANDLE_DI_FLAG((1 << 28), LittleEndian) HANDLE_DI_FLAG((1 << 29), AllCallsDescribed) // To avoid needing a dedicated value for IndirectVirtualBase, we use @@ -91,13 +98,50 @@ // for defaulted functions HANDLE_DISP_FLAG((1u << 9), Deleted) HANDLE_DISP_FLAG((1u << 11), ObjCDirect) +HANDLE_DISP_FLAG((1u << 12), Explicit) +HANDLE_DISP_FLAG((1u << 13), Prototyped) +HANDLE_DISP_FLAG((1u << 14), NoReturn) +HANDLE_DISP_FLAG((1u << 15), Thunk) +HANDLE_DISP_FLAG((1u << 16), AllCallsDescribed) #ifdef DISP_FLAG_LARGEST_NEEDED // Intended to be used with ADT/BitmaskEnum.h. // NOTE: Always must be equal to largest flag, check this when adding new flags. -HANDLE_DISP_FLAG((1 << 11), Largest) +HANDLE_DISP_FLAG((1 << 16), Largest) #undef DISP_FLAG_LARGEST_NEEDED #endif +// BasicType flags kept in DIBasicType. + +// Use this as a zero/initialization value. +// For example: void foo(DIBTFlags Flags = BTFlagZero). +HANDLE_DIBT_FLAG(0, Zero) +HANDLE_DIBT_FLAG(1u, LittleEndian) +HANDLE_DIBT_FLAG(2u, BigEndian) + +#ifdef DIBT_FLAG_LARGEST_NEEDED +// Intended to be used with ADT/BitmaskEnum.h. +// NOTE: Always must be equal to largest flag, check this when adding new flags. +HANDLE_DIBT_FLAG(2u, Largest) +#undef DIBT_FLAG_LARGEST_NEEDED +#endif + +// LocalVariable flags kept in DILocalVariable. + +// Use this as a zero/initialization value. +// For example: void foo(DIVARFlags Flags = VARFlagZero). +HANDLE_DIVAR_FLAG(0, Zero) +HANDLE_DIVAR_FLAG(1u, FlagArtificial) +HANDLE_DIVAR_FLAG(2u, FlagObjectPointer) + +#ifdef DIVAR_FLAG_LARGEST_NEEDED +// Intended to be used with ADT/BitmaskEnum.h. +// NOTE: Always must be equal to largest flag, check this when adding new flags. +HANDLE_DIVAR_FLAG(2u, Largest) +#undef DIVAR_FLAG_LARGEST_NEEDED +#endif + #undef HANDLE_DI_FLAG #undef HANDLE_DISP_FLAG +#undef HANDLE_DIBT_FLAG +#undef HANDLE_DIVAR_FLAG diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -665,8 +665,6 @@ bool isTypePassByReference() const { return getFlags() & FlagTypePassByReference; } - bool isBigEndian() const { return getFlags() & FlagBigEndian; } - bool isLittleEndian() const { return getFlags() & FlagLittleEndian; } bool getExportSymbols() const { return getFlags() & FlagExportSymbols; } static bool classof(const Metadata *MD) { @@ -690,50 +688,79 @@ friend class LLVMContextImpl; friend class MDNode; +public: + /// Debug BasicType flags. + enum DIBTFlags : uint32_t { +#define HANDLE_DIBT_FLAG(ID, NAME) BTFlag##NAME = ID, +#define DIBT_FLAG_LARGEST_NEEDED +#include "llvm/IR/DebugInfoFlags.def" + LLVM_MARK_AS_BITMASK_ENUM(BTFlagLargest) + }; + + static DIBTFlags getFlag(StringRef Flag); + static StringRef getFlagString(DIBTFlags Flag); + + /// Split up a flags bitfield for easier printing. + /// + /// Split \c Flags into \c SplitFlags, a vector of its components. Returns + /// any remaining (unrecognized) bits. + static DIBTFlags splitFlags(DIBTFlags Flags, + SmallVectorImpl &SplitFlags); + + // Helper for converting old bitfields to new flags word. + static DIBTFlags toBTFlags(bool IsBigEndian, bool IsLittleEndian) { + return static_cast( + (IsBigEndian ? BTFlagBigEndian : BTFlagZero) | + (IsLittleEndian ? BTFlagLittleEndian : BTFlagZero)); + } + +private: + DIBTFlags BTFlags; unsigned Encoding; DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, ArrayRef Ops) + DIBTFlags BTFlags, ArrayRef Ops) : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, - Flags, Ops), - Encoding(Encoding) {} + FlagZero, Ops), + BTFlags(BTFlags), Encoding(Encoding) {} ~DIBasicType() = default; static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, + DIBTFlags BTFlags, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), - SizeInBits, AlignInBits, Encoding, Flags, Storage, + SizeInBits, AlignInBits, Encoding, BTFlags, Storage, ShouldCreate); } + static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, + DIBTFlags BTFlags, StorageType Storage, bool ShouldCreate = true); TempDIBasicType cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getSizeInBits(), - getAlignInBits(), getEncoding(), getFlags()); + getAlignInBits(), getEncoding(), getBTFlags()); } public: DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name), - (Tag, Name, 0, 0, 0, FlagZero)) + (Tag, Name, 0, 0, 0, BTFlagZero)) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), + uint32_t AlignInBits, unsigned Encoding, DIBTFlags Flags), (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, MDString *Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), + uint32_t AlignInBits, unsigned Encoding, DIBTFlags Flags), (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) TempDIBasicType clone() const { return cloneImpl(); } - + DIBTFlags getBTFlags() const { return BTFlags; } unsigned getEncoding() const { return Encoding; } enum class Signedness { Signed, Unsigned }; @@ -741,6 +768,8 @@ /// Return the signedness of this type, or None if this type is neither /// signed nor unsigned. Optional getSignedness() const; + bool isBigEndian() const { return getBTFlags() & BTFlagBigEndian; } + bool isLittleEndian() const { return getBTFlags() & BTFlagLittleEndian; } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DIBasicTypeKind; @@ -1643,6 +1672,28 @@ (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero)); } + static void moveDItoSPFlags(DIFlags &Flags, DISPFlags &SPFlags) { + const uint32_t DIFlagExplicit = 1 << 7; + const uint32_t DIFlagPrototyped = 1 << 8; + const uint32_t DIFlagNoReturn = 1 << 20; + const uint32_t DIFlagThunk = 1 << 25; + const uint32_t DIFlagAllCallsDescribed = 1 << 29; + if (Flags & DIFlagExplicit) + SPFlags |= SPFlagExplicit; + if (Flags & DIFlagPrototyped) + SPFlags |= SPFlagPrototyped; + if (Flags & DIFlagNoReturn) + SPFlags |= SPFlagNoReturn; + if (Flags & DIFlagThunk) + SPFlags |= SPFlagThunk; + if (Flags & DIFlagAllCallsDescribed) + SPFlags |= SPFlagAllCallsDescribed; + + Flags = static_cast( + Flags & ~(DIFlagExplicit | DIFlagPrototyped | DIFlagNoReturn | + DIFlagThunk | DIFlagAllCallsDescribed)); + } + private: DIFlags Flags; DISPFlags SPFlags; @@ -1751,10 +1802,10 @@ bool isPublic() const { return (getFlags() & FlagAccessibility) == FlagPublic; } - bool isExplicit() const { return getFlags() & FlagExplicit; } - bool isPrototyped() const { return getFlags() & FlagPrototyped; } + bool isExplicit() const { return getSPFlags() & SPFlagExplicit; } + bool isPrototyped() const { return getSPFlags() & SPFlagPrototyped; } bool areAllCallsDescribed() const { - return getFlags() & FlagAllCallsDescribed; + return getSPFlags() & SPFlagAllCallsDescribed; } bool isPure() const { return getSPFlags() & SPFlagPure; } bool isElemental() const { return getSPFlags() & SPFlagElemental; } @@ -1782,12 +1833,12 @@ /// Check if this is marked as noreturn. /// /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn - bool isNoReturn() const { return getFlags() & FlagNoReturn; } + bool isNoReturn() const { return getSPFlags() & SPFlagNoReturn; } // Check if this routine is a compiler-generated thunk. // // Returns true if this subprogram is a thunk generated by the compiler. - bool isThunk() const { return getFlags() & FlagThunk; } + bool isThunk() const { return getSPFlags() & SPFlagThunk; } DIScope *getScope() const { return cast_or_null(getRawScope()); } diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -928,6 +928,11 @@ return lltok::DISPFlag; } + if (Keyword.startswith("DIBTFlag")) { + StrVal.assign(Keyword.begin(), Keyword.end()); + return lltok::DIBTFlag; + } + if (Keyword.startswith("CSK_")) { StrVal.assign(Keyword.begin(), Keyword.end()); return lltok::ChecksumKind; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3870,6 +3870,10 @@ DISPFlagField() : MDFieldImpl(DISubprogram::SPFlagZero) {} }; +struct DIBTFlagField : public MDFieldImpl { + DIBTFlagField() : MDFieldImpl(DIBasicType::BTFlagZero) {} +}; + struct MDSignedField : public MDFieldImpl { int64_t Min; int64_t Max; @@ -4162,6 +4166,46 @@ return false; } +/// DIBTFlagField +/// ::= uint32 +/// ::= DIBTFlagBigEndian +/// ::= DIBTFlagBigEndian '|' DIBTFlag* '|' uint32 +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIBTFlagField &Result) { + + // Parser for a single flag. + auto parseFlag = [&](DIBasicType::DIBTFlags &Val) { + if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) { + uint32_t TempVal = static_cast(Val); + bool Res = ParseUInt32(TempVal); + Val = static_cast(TempVal); + return Res; + } + + if (Lex.getKind() != lltok::DIBTFlag) + return TokError("expected debug info flag"); + + Val = DIBasicType::getFlag(Lex.getStrVal()); + if (!Val) + return TokError(Twine("invalid basicType debug info flag '") + + Lex.getStrVal() + "'"); + Lex.Lex(); + return false; + }; + + // Parse the flags and combine them together. + DIBasicType::DIBTFlags Combined = DIBasicType::BTFlagZero; + do { + DIBasicType::DIBTFlags Val; + if (parseFlag(Val)) + return true; + Combined |= Val; + } while (EatIfPresent(lltok::bar)); + + Result.assign(Combined); + return false; +} + /// DISPFlagField /// ::= uint32 /// ::= DISPFlagVector @@ -4490,9 +4534,8 @@ return false; } -/// ParseDIBasicType: /// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, -/// encoding: DW_ATE_encoding, flags: 0) +/// encoding: DW_ATE_encoding, btFlags: DIBTFlagBigEndian) bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ @@ -4500,12 +4543,11 @@ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(encoding, DwarfAttEncodingField, ); \ - OPTIONAL(flags, DIFlagField, ); + OPTIONAL(btFlags, DIBTFlagField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val, - align.Val, encoding.Val, flags.Val)); + align.Val, encoding.Val, btFlags.Val)); return false; } @@ -4715,10 +4757,14 @@ spFlags.Seen ? spFlags.Val : DISubprogram::toSPFlags(isLocal.Val, isDefinition.Val, isOptimized.Val, virtuality.Val); + // some of the DIFlags were moved to SPFlags + DISubprogram::moveDItoSPFlags(flags.Val, SPFlags); + if ((SPFlags & DISubprogram::SPFlagDefinition) && !IsDistinct) return Lex.Error( Loc, "missing 'distinct', required for !DISubprogram that is a Definition"); + Result = GET_OR_DISTINCT( DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -462,6 +462,7 @@ DwarfOp, // DW_OP_foo DIFlag, // DIFlagFoo DISPFlag, // DISPFlagFoo + DIBTFlag, // DIBTFlagFoo DwarfMacinfo, // DW_MACINFO_foo ChecksumKind, // CSK_foo diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1293,14 +1293,27 @@ if (Record.size() < 6 || Record.size() > 7) return error("Invalid record"); - IsDistinct = Record[0]; - DINode::DIFlags Flags = (Record.size() > 6) ? - static_cast(Record[6]) : DINode::FlagZero; + IsDistinct = Record[0] & 1; + bool HasBTFlags = Record[0] & 2; + DIBasicType::DIBTFlags BTFlags = DIBasicType::BTFlagZero; + + // BasicType-specific flags in DIFlag were moved to DIBTFlags. + const unsigned DIFlagBigEndian = (1 << 27); + const unsigned DIFlagLittleEndian = (1 << 28); + if (Record.size() > 6) { + if (HasBTFlags) + BTFlags = static_cast(Record[6]); + else { + DINode::DIFlags Flags = static_cast(Record[6]); + BTFlags = DIBasicType::toBTFlags(Flags & DIFlagBigEndian, + Flags & DIFlagLittleEndian); + } + } MetadataList.assignValue( GET_OR_DISTINCT(DIBasicType, (Context, Record[1], getMDString(Record[2]), Record[3], - Record[4], Record[5], Flags)), + Record[4], Record[5], BTFlags)), NextMetadataNo); NextMetadataNo++; break; @@ -1489,9 +1502,8 @@ return error("Invalid record"); bool HasSPFlags = Record[0] & 4; - DINode::DIFlags Flags; - DISubprogram::DISPFlags SPFlags; + DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero; if (!HasSPFlags) Flags = static_cast(Record[11 + 2]); else { @@ -1499,6 +1511,9 @@ SPFlags = static_cast(Record[9]); } + // Some flags were moved from DIFlags to SPFlags + DISubprogram::moveDItoSPFlags(Flags, SPFlags); + // Support for old metadata when // subprogram specific flags are placed in DIFlags. const unsigned DIFlagMainSubprogram = 1 << 21; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1540,13 +1540,14 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + const uint64_t HasBTFlagsFlag = 1 << 1; + Record.push_back(uint64_t(N->isDistinct()) | HasBTFlagsFlag); Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(N->getSizeInBits()); Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); - Record.push_back(N->getFlags()); + Record.push_back(N->getBTFlags()); Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1619,6 +1619,7 @@ void printBool(StringRef Name, bool Value, Optional Default = None); void printDIFlags(StringRef Name, DINode::DIFlags Flags); void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags); + void printDIBTFlags(StringRef Name, DIBasicType::DIBTFlags Flags); template void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString, bool ShouldSkipZero = true); @@ -1717,6 +1718,26 @@ Out << FlagsFS << Extra; } +void MDFieldPrinter::printDIBTFlags(StringRef Name, + DIBasicType::DIBTFlags Flags) { + if (!Flags) { + return; + } + + Out << FS << Name << ": "; + SmallVector SplitFlags; + auto Extra = DIBasicType::splitFlags(Flags, SplitFlags); + + FieldSeparator FlagsFS(" | "); + for (auto F : SplitFlags) { + auto StringF = DIBasicType::getFlagString(F); + assert(!StringF.empty() && "Expected valid flag"); + Out << FlagsFS << StringF; + } + if (Extra || SplitFlags.empty()) + Out << FlagsFS << Extra; +} + void MDFieldPrinter::printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags) { // Always print this field, because no flags in the IR at all will be @@ -1841,7 +1862,7 @@ Printer.printInt("align", N->getAlignInBits()); Printer.printDwarfEnum("encoding", N->getEncoding(), dwarf::AttributeEncodingString); - Printer.printDIFlags("flags", N->getFlags()); + Printer.printDIBTFlags("btFlags", N->getBTFlags()); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -260,7 +260,7 @@ DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, - DINode::DIFlags Flags) { + DIBasicType::DIBTFlags Flags) { assert(!Name.empty() && "Unable to create type without name"); return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits, 0, Encoding, Flags); diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -726,6 +726,11 @@ return static_cast(Flags); } +static DIBasicType::DIBTFlags pack_into_DIBTFlags(bool IsBigEndian, + bool IsLittleEndian) { + return DIBasicType::toBTFlags(IsBigEndian, IsLittleEndian); +} + static DISubprogram::DISPFlags pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized) { return DISubprogram::toSPFlags(IsLocalToUnit, IsDefinition, IsOptimized); @@ -811,12 +816,16 @@ LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool IsLocalToUnit, LLVMBool IsDefinition, unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized) { + auto DIFlags = map_from_llvmDIFlags(Flags); + auto SPDIFlags = + pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized); + // some Flags were moved from DIFlag to SPFlag. + DISubprogram::moveDItoSPFlags(DIFlags, SPDIFlags); + return wrap(unwrap(Builder)->createFunction( unwrapDI(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen}, unwrapDI(File), LineNo, unwrapDI(Ty), ScopeLine, - map_from_llvmDIFlags(Flags), - pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), nullptr, - nullptr, nullptr)); + DIFlags, SPDIFlags, nullptr, nullptr, nullptr)); } @@ -1018,9 +1027,10 @@ size_t NameLen, uint64_t SizeInBits, LLVMDWARFTypeEncoding Encoding, LLVMDIFlags Flags) { - return wrap(unwrap(Builder)->createBasicType({Name, NameLen}, - SizeInBits, Encoding, - map_from_llvmDIFlags(Flags))); + auto BTFlags = pack_into_DIBTFlags(Flags & LLVMDIFlagBigEndian, + Flags & LLVMDIFlagLittleEndian); + return wrap(unwrap(Builder)->createBasicType({Name, NameLen}, SizeInBits, + Encoding, BTFlags)); } LLVMMetadataRef LLVMDIBuilderCreatePointerType( diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -344,14 +344,46 @@ DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, + DIBTFlags BTFlags, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIBasicType, - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)); + DEFINE_GETIMPL_LOOKUP( + DIBasicType, (Tag, Name, SizeInBits, AlignInBits, Encoding, BTFlags)); Metadata *Ops[] = {nullptr, nullptr, Name}; - DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding, - Flags), Ops); + DEFINE_GETIMPL_STORE(DIBasicType, + (Tag, SizeInBits, AlignInBits, Encoding, BTFlags), Ops); +} + +DIBasicType::DIBTFlags DIBasicType::getFlag(StringRef Flag) { + return StringSwitch(Flag) +#define HANDLE_DIBT_FLAG(ID, NAME) .Case("DIBTFlag" #NAME, BTFlag##NAME) +#include "llvm/IR/DebugInfoFlags.def" + .Default(BTFlagZero); +} + +StringRef DIBasicType::getFlagString(DIBTFlags Flag) { + switch (Flag) { + // Appease a warning. +#define HANDLE_DIBT_FLAG(ID, NAME) \ + case BTFlag##NAME: \ + return "DIBTFlag" #NAME; +#include "llvm/IR/DebugInfoFlags.def" + } + return ""; +} + +DIBasicType::DIBTFlags +DIBasicType::splitFlags(DIBTFlags Flags, + SmallVectorImpl &SplitFlags) { + // Multi-bit fields can require special handling. In our case all its values + // happen to be single-bit values. +#define HANDLE_DIBT_FLAG(ID, NAME) \ + if (DIBTFlags Bit = Flags & BTFlag##NAME) { \ + SplitFlags.push_back(Bit); \ + Flags &= ~Bit; \ + } +#include "llvm/IR/DebugInfoFlags.def" + return Flags; } Optional DIBasicType::getSignedness() const { diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -379,22 +379,22 @@ uint64_t SizeInBits; uint32_t AlignInBits; unsigned Encoding; - unsigned Flags; + unsigned BTFlags; MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, unsigned Flags) + uint32_t AlignInBits, unsigned Encoding, unsigned BTFlags) : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), - Encoding(Encoding), Flags(Flags) {} + Encoding(Encoding), BTFlags(BTFlags) {} MDNodeKeyImpl(const DIBasicType *N) : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), - AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), Flags(N->getFlags()) {} + AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), + BTFlags(N->getBTFlags()) {} bool isKeyOf(const DIBasicType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && SizeInBits == RHS->getSizeInBits() && AlignInBits == RHS->getAlignInBits() && - Encoding == RHS->getEncoding() && - Flags == RHS->getFlags(); + Encoding == RHS->getEncoding() && BTFlags == RHS->getBTFlags(); } unsigned getHashValue() const { diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll --- a/llvm/test/Assembler/debug-info.ll +++ b/llvm/test/Assembler/debug-info.ll @@ -95,7 +95,7 @@ !39 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A") !40 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A") -; CHECK-NEXT: !38 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian) -; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian) -!41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian) -!42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian) +; CHECK-NEXT: !38 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagBigEndian) +; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagLittleEndian) +!41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagBigEndian) +!42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagLittleEndian) diff --git a/llvm/test/Assembler/disubprogram.ll b/llvm/test/Assembler/disubprogram.ll --- a/llvm/test/Assembler/disubprogram.ll +++ b/llvm/test/Assembler/disubprogram.ll @@ -6,8 +6,8 @@ ret void } -; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !17, !19, !20, !21} +; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !17, !19, !20, !21, !22} !0 = !{null} !1 = distinct !DICompositeType(tag: DW_TAG_structure_type) @@ -28,7 +28,7 @@ ; CHECK: !9 = !DISubprogram(scope: null, spFlags: 0) !9 = !DISubprogram(isDefinition: false) -; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6) +; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 10, thisAdjustment: 3, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagNoReturn, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6) !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, isLocal: true, isDefinition: true, scopeLine: 8, @@ -69,7 +69,7 @@ isDefinition: true, scopeLine: 2, isOptimized: false, unit: !8, thrownTypes: !13) -; CHECK: !15 = distinct !DISubprogram({{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, +; CHECK: !15 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped, !15 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 0, @@ -86,9 +86,11 @@ ; CHECK: !DISubprogram({{.*}}subroutine2{{.*}}, spFlags: DISPFlagDefinition | DISPFlagElemental, ; CHECK: !DISubprogram({{.*}}subroutine3{{.*}}, spFlags: DISPFlagDefinition | DISPFlagRecursive, ; CHECK: !DISubprogram({{.*}}subroutine4{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, +; CHECK: !DISubprogram({{.*}}subroutine5{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive | DISPFlagNoReturn | DISPFlagThunk | DISPFlagAllCallsDescribed, !17 = distinct !DISubprogram(name: "subroutine1", scope: !1, file: !2, line: 1, type: !18, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagPure, unit: !8, retainedNodes: !6) !18 = !DISubroutineType(types: !0) !19 = distinct !DISubprogram(name: "subroutine2", scope: !1, file: !2, line: 5, type: !18, scopeLine: 6, spFlags: DISPFlagDefinition | DISPFlagElemental, unit: !8, retainedNodes: !6) !20 = distinct !DISubprogram(name: "subroutine3", scope: !1, file: !2, line: 9, type: !18, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagRecursive, unit: !8, retainedNodes: !6) !21 = distinct !DISubprogram(name: "subroutine4", scope: !1, file: !2, line: 13, type: !18, scopeLine: 14, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !8, retainedNodes: !6) +!22 = distinct !DISubprogram(name: "subroutine5", scope: !1, file: !2, line: 13, type: !18, scopeLine: 14, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive | DISPFlagThunk | DISPFlagNoReturn | DISPFlagAllCallsDescribed, unit: !8, retainedNodes: !6) diff --git a/llvm/test/Bitcode/DIBasicType.ll b/llvm/test/Bitcode/DIBasicType.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/DIBasicType.ll @@ -0,0 +1,34 @@ +; RUN: llvm-dis -o - %s.bc | FileCheck %s +; CHECK: = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: ![[#LETYPE:]], isLocal: false, isDefinition: true) +; CHECK: = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 1, type: ![[#BETYPE:]], isLocal: false, isDefinition: true) +; CHECK: ![[#BETYPE]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, btFlags: DIBTFlagBigEndian) +; CHECK: ![[#LETYPE]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, btFlags: DIBTFlagLittleEndian) + +@a = common dso_local global i32 0, align 4, !dbg !0 +@b = common dso_local global i32 0, align 4, !dbg !6 + +define dso_local void @main() !dbg !12 { +entry: + ret void, !dbg !15 +} + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "main.c", directory: "/dir") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, flags: DIFlagBigEndian) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, flags: DIFlagLittleEndian) +!10 = !{i32 7, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 2, type: !13, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4) +!13 = !DISubroutineType(types: !14) +!14 = !{null} +!15 = !DILocation(line: 2, column: 14, scope: !12) + diff --git a/llvm/test/Bitcode/DIBasicType.ll.bc b/llvm/test/Bitcode/DIBasicType.ll.bc new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@getTag()); EXPECT_EQ("special", N->getName()); EXPECT_EQ(33u, N->getSizeInBits()); @@ -1213,31 +1212,31 @@ EXPECT_EQ(0u, N->getLine()); EXPECT_EQ(DINode::FlagZero, N->getFlags()); EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 7, DINode::FlagZero)); + 26, 7, DIBasicType::BTFlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, - "special", 33, 26, 7, DINode::FlagZero)); - EXPECT_NE(N, - DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7, - DINode::FlagZero)); + "special", 33, 26, 7, DIBasicType::BTFlagZero)); + EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, + 7, DIBasicType::BTFlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32, - 26, 7, DINode::FlagZero)); + 26, 7, DIBasicType::BTFlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 25, 7, DINode::FlagZero)); + 25, 7, DIBasicType::BTFlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 6, DINode::FlagZero)); + 26, 6, DIBasicType::BTFlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 7, DINode::FlagBigEndian)); + 26, 7, DIBasicType::BTFlagBigEndian)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 7, DINode::FlagLittleEndian)); + 26, 7, DIBasicType::BTFlagLittleEndian)); TempDIBasicType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } TEST_F(DIBasicTypeTest, getWithLargeValues) { - auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", - UINT64_MAX, UINT32_MAX - 1, 7, DINode::FlagZero); + auto *N = + DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", UINT64_MAX, + UINT32_MAX - 1, 7, DIBasicType::BTFlagZero); EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); } @@ -1251,7 +1250,7 @@ EXPECT_EQ(0u, N->getAlignInBits()); EXPECT_EQ(0u, N->getEncoding()); EXPECT_EQ(0u, N->getLine()); - EXPECT_EQ(DINode::FlagZero, N->getFlags()); + EXPECT_EQ(DIBasicType::BTFlagZero, N->getBTFlags()); } typedef MetadataTest DITypeTest; @@ -1259,7 +1258,7 @@ TEST_F(DITypeTest, clone) { // Check that DIType has a specialized clone that returns TempDIType. DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32, - dwarf::DW_ATE_signed, DINode::FlagZero); + dwarf::DW_ATE_signed, DIBasicType::BTFlagZero); TempDIType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));