summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/utils
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-01-14 19:55:43 +0000
committerpatrick <patrick@openbsd.org>2017-01-14 19:55:43 +0000
commitbd3306aecb3a15e8967143b8cdbbccf2b1b19b74 (patch)
tree309a8132b44564b9e634c0da6815187ce8eab27c /gnu/llvm/tools/clang/utils
parentkillp -a should not kill the window if only one pane. (diff)
downloadwireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.tar.xz
wireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.zip
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm/tools/clang/utils')
-rw-r--r--gnu/llvm/tools/clang/utils/ClangVisualizers/CMakeLists.txt7
-rw-r--r--gnu/llvm/tools/clang/utils/ClangVisualizers/clang.natvis586
-rw-r--r--gnu/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp565
-rw-r--r--gnu/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp13
-rw-r--r--gnu/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp22
-rw-r--r--gnu/llvm/tools/clang/utils/TableGen/TableGen.cpp2
-rwxr-xr-xgnu/llvm/tools/clang/utils/analyzer/SATestBuild.py56
-rw-r--r--gnu/llvm/tools/clang/utils/modfuzz.py166
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/CMakeLists.txt47
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/cxx/hello_world.cpp1
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/lit.cfg5
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/lit.site.cfg.in5
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/order-files.lit.cfg41
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/order-files.lit.site.cfg.in21
-rw-r--r--gnu/llvm/tools/clang/utils/perf-training/perf-helper.py385
15 files changed, 1722 insertions, 200 deletions
diff --git a/gnu/llvm/tools/clang/utils/ClangVisualizers/CMakeLists.txt b/gnu/llvm/tools/clang/utils/ClangVisualizers/CMakeLists.txt
new file mode 100644
index 00000000000..16d118a421b
--- /dev/null
+++ b/gnu/llvm/tools/clang/utils/ClangVisualizers/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Do this by hand instead of using add_llvm_utilities(), which
+# tries to create a corresponding executable, which we don't want.
+if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION)
+ set(CLANG_VISUALIZERS clang.natvis)
+ add_custom_target(ClangVisualizers SOURCES ${CLANG_VISUALIZERS})
+ set_target_properties(ClangVisualizers PROPERTIES FOLDER "Utils")
+endif()
diff --git a/gnu/llvm/tools/clang/utils/ClangVisualizers/clang.natvis b/gnu/llvm/tools/clang/utils/ClangVisualizers/clang.natvis
new file mode 100644
index 00000000000..6e3ca96ffde
--- /dev/null
+++ b/gnu/llvm/tools/clang/utils/ClangVisualizers/clang.natvis
@@ -0,0 +1,586 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Visual Studio Native Debugging Visualizers for LLVM
+
+For Visual Studio 2013 only, put this file into
+"%USERPROFILE%\Documents\Visual Studio 2013\Visualizers" or create a symbolic link so it updates automatically.
+
+For later versions of Visual Studio, no setup is required-->
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <Type Name="clang::Type">
+ <!-- To visualize clang::Types, we need to look at TypeBits.TC to determine the actual
+ type subclass and manually dispatch accordingly (Visual Studio can't identify the real type
+ because clang::Type has no virtual members hence no RTTI).
+
+ Views:
+ "cmn": Visualization that is common to all clang::Type subclasses
+ "poly": Visualization that is specific to the actual clang::Type subclass. The subtype-specific
+ <DisplayString> is typically as C++-like as possible (like in dump()) with <Expand>
+ containing all the gory details.
+ "cpp": Only occasionally used when we need to distinguish between an ordinary view and a C++-like view.
+ -->
+ <DisplayString IncludeView="cmn" Condition="TypeBits.TC==clang::LocInfoType::LocInfo">LocInfoType</DisplayString>
+ <DisplayString IncludeView="cmn">{(clang::Type::TypeClass)TypeBits.TC, en}Type</DisplayString>
+ <!-- Dispatch to visualizers for the actual Type subclass -->
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Builtin" IncludeView="poly">{*(clang::BuiltinType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Pointer" IncludeView="poly">{*(clang::PointerType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::LValueReference" IncludeView="poly">{*(clang::LValueReferenceType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::RValueReference" IncludeView="poly">{*(clang::RValueReferenceType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Attributed" IncludeView="poly">{*(clang::AttributedType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::TemplateTypeParm" IncludeView="poly">{*(clang::TemplateTypeParmType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::SubstTemplateTypeParm" IncludeView="poly">{*(clang::SubstTemplateTypeParmType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Record" IncludeView="poly">{*(clang::RecordType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::Record" IncludeView="cpp">{*(clang::RecordType *)this,view(cpp)}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::FunctionProto" IncludeView="poly">{*(clang::FunctionProtoType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::TemplateSpecialization" IncludeView="poly">{*(clang::TemplateSpecializationType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::InjectedClassName" IncludeView="poly">{*(clang::InjectedClassNameType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::Type::TypeClass::PackExpansion" IncludeView="poly">{*(clang::PackExpansionType *)this}</DisplayString>
+ <DisplayString Condition="TypeBits.TC==clang::LocInfoType::LocInfo" IncludeView="poly">{*(clang::LocInfoType *)this}</DisplayString>
+ <DisplayString IncludeView="cpp">{*this,view(poly)}</DisplayString>
+ <DisplayString IncludeView="poly">{*this,view(cmn)}</DisplayString> <!-- Not yet implemented Type subclass -->
+ <DisplayString>{*this,view(cmn)} {{{*this,view(poly)}}}</DisplayString>
+ <Expand>
+ <Item Name="TypeClass" IncludeView="cmn">(clang::Type::TypeClass)TypeBits.TC</Item>
+ <Item Name="Flags" IncludeView="cmn">TypeBits</Item>
+ <Item Name="Canonical" IncludeView="cmn">CanonicalType</Item>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Builtin">*(clang::BuiltinType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Pointer">*(clang::PointerType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::LValueReference">*(clang::LValueReferenceType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::RValueReference">*(clang::RValueReferenceType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Attributed">*(clang::AttributedType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::TemplateTypeParm">(clang::TemplateTypeParmType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::SubstTemplateTypeParm">(clang::SubstTemplateTypeParmType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::Record">(clang::RecordType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::FunctionProto">(clang::FunctionProtoType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::TemplateSpecialization">(clang::TemplateSpecializationType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::InjectedClassName">(clang::InjectedClassNameType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::Type::TypeClass::PackExpansion">(clang::PackExpansionType *)this</ExpandedItem>
+ <ExpandedItem ExcludeView="cmn" Condition="TypeBits.TC==clang::LocInfoType::LocInfo">(clang::LocInfoType *)this</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::PointerType">
+ <DisplayString>{PointeeType, view(poly)} *</DisplayString>
+ <Expand>
+ <Item Name="PointeeType">PointeeType</Item>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ </Expand>
+ </Type>
+ <!-- We visualize all inner types for clang reference types. So a rvalue reference to an lvalue reference
+ to an int would visual as int &amp; &amp;&amp; This is a little different than GetPointeeType(),
+ but more clearly displays the data structure and seems natural -->
+ <Type Name="clang::LValueReferenceType">
+ <DisplayString>{((clang::ReferenceType *)this)-&gt;PointeeType,view(cpp)} &amp;</DisplayString>
+ <Expand>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ <Item Name="PointeeType">PointeeType</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::RValueReferenceType">
+ <DisplayString>{((clang::ReferenceType *)this)-&gt;PointeeType,view(cpp)} &amp;&amp;</DisplayString>
+ <Expand>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ <Item Name="PointeeType">PointeeType</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::AttributedType">
+ <DisplayString>{ModifiedType} Attribute={(clang::AttributedType::Kind)AttributedTypeBits.AttrKind}</DisplayString>
+ </Type>
+
+ <!-- Unfortunately, Visual Studio has trouble seeing the PointerBitMask member PointerIntUnion, so I hardwire it to 2 bits-->
+ <Type Name="clang::DeclContext">
+ <DisplayString>{(clang::Decl::Kind)DeclKind,en}Decl</DisplayString>
+ <Expand>
+ <Item Name="DeclKind">(clang::Decl::Kind)DeclKind,en</Item>
+ <Synthetic Name="Members">
+ <DisplayString></DisplayString>
+ <Expand>
+ <LinkedListItems>
+ <HeadPointer>FirstDecl</HeadPointer>
+ <NextPointer>(clang::Decl *)(NextInContextAndBits.Value &amp; ~3)</NextPointer>
+ <ValueNode>*this</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Synthetic>
+ </Expand>
+ </Type>
+ <Type Name="clang::FieldDecl">
+ <DisplayString>Field {{{*(clang::DeclaratorDecl *)this,view(cpp)nd}}}</DisplayString>
+ </Type>
+ <Type Name="clang::CXXMethodDecl">
+ <DisplayString IncludeView="cpp">{*(clang::FunctionDecl *)this,nd}</DisplayString>
+ <DisplayString>Method {{{*this,view(cpp)}}}</DisplayString>
+ </Type>
+ <Type Name="clang::CXXConstructorDecl">
+ <DisplayString>Constructor {{{Name,view(cpp)}({*(clang::FunctionDecl *)this,view(parm0)nd})}}</DisplayString>
+ </Type>
+ <Type Name="clang::CXXDestructorDecl">
+ <DisplayString>Destructor {{~{Name,view(cpp)}()}}</DisplayString>
+ </Type>
+ <Type Name="clang::TemplateTypeParmDecl">
+ <DisplayString IncludeView="TorC" Condition="Typename">typename</DisplayString>
+ <DisplayString IncludeView="TorC" Condition="!Typename">class</DisplayString>
+ <DisplayString IncludeView="MaybeEllipses" Condition="((TemplateTypeParmType *)TypeForDecl)->CanTTPTInfo.ParameterPack">...</DisplayString>
+ <DisplayString IncludeView="MaybeEllipses" Condition="!((TemplateTypeParmType *)TypeForDecl)->CanTTPTInfo.ParameterPack"></DisplayString>
+ <DisplayString>{*this,view(TorC)} {*this,view(MaybeEllipses)}{Name,view(cpp)}</DisplayString>
+ </Type>
+ <Type Name="clang::TemplateDecl">
+ <DisplayString>template{*TemplateParams} {*TemplatedDecl};</DisplayString>
+ </Type>
+ <Type Name="clang::NamedDecl" >
+ <DisplayString IncludeView="cpp">{Name,view(cpp)}</DisplayString>
+ <DisplayString>{Name}</DisplayString>
+ </Type>
+ <Type Name="clang::TagDecl">
+ <DisplayString IncludeView="implicit" Condition="Implicit">implicit{" ",sb}</DisplayString>
+ <DisplayString IncludeView="implicit"></DisplayString>
+ <DisplayString IncludeView="modifiers">{*this,view(implicit)}</DisplayString>
+ <DisplayString IncludeView="cpp">{*this,view(modifiers)}{Name,view(cpp)}</DisplayString>
+ <DisplayString Condition="TagDeclKind==clang::TagTypeKind::TTK_Struct">{*this,view(modifiers)}struct {Name,view(cpp)}</DisplayString>
+ <DisplayString Condition="TagDeclKind==clang::TagTypeKind::TTK_Interface">{*this,view(modifiers)}interface {Name,view(cpp)}</DisplayString>
+ <DisplayString Condition="TagDeclKind==clang::TagTypeKind::TTK_Union">{*this,view(modifiers)}union {Name,view(cpp)}</DisplayString>
+ <DisplayString Condition="TagDeclKind==clang::TagTypeKind::TTK_Class">{*this,view(modifiers)}class {Name,view(cpp)}</DisplayString>
+ <DisplayString Condition="TagDeclKind==clang::TagTypeKind::TTK_Enum">{*this,view(modifiers)}enum {Name,view(cpp)}</DisplayString>
+ <Expand>
+ <ExpandedItem>(clang::DeclContext *)this</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::TagType">
+ <DisplayString IncludeView="cpp">{*decl,view(cpp)}</DisplayString>
+ <DisplayString>{*decl}</DisplayString>
+ <Expand>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ <Item Name="decl">decl</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::RecordType">
+ <DisplayString IncludeView="cpp">{*(clang::TagType *)this,view(cpp)}</DisplayString>
+ <DisplayString>{*(clang::TagType *)this}</DisplayString>
+ <Expand>
+ <Item Name="TagType">*(clang::TagType *)this</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::SubstTemplateTypeParmType">
+ <DisplayString>{*Replaced,view(cpp)} &lt;= {CanonicalType,view(cpp)}</DisplayString>
+ <Expand>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ <Item Name="Replaced">*Replaced</Item>
+ </Expand>
+ </Type>
+ <!-- We only show the first 5 parameter types in the display string (can't figure out how to loop in DisplayString)
+ but the expansion has all parameters -->
+ <Type Name="clang::FunctionProtoType">
+ <DisplayString IncludeView="retType">{ResultType,view(cpp)}</DisplayString>
+ <DisplayString IncludeView="parm0" Condition="NumParams==0"></DisplayString>
+ <DisplayString IncludeView="parm0">{*(clang::QualType *)(this+1),view(cpp)}{*this,view(parm1)}</DisplayString>
+ <DisplayString IncludeView="parm1" Condition="NumParams==1"></DisplayString>
+ <DisplayString IncludeView="parm1">, {*((clang::QualType *)(this+1)+1),view(cpp)}{*this,view(parm2)}</DisplayString>
+ <DisplayString IncludeView="parm2" Condition="NumParams==2"></DisplayString>
+ <DisplayString IncludeView="parm2">, {*((clang::QualType *)(this+1)+2),view(cpp)}{*this,view(parm3)}</DisplayString>
+ <DisplayString IncludeView="parm3" Condition="NumParams==3"></DisplayString>
+ <DisplayString IncludeView="parm3">, {*((clang::QualType *)(this+1)+3),view(cpp)}{*this,view(parm4)}</DisplayString>
+ <DisplayString IncludeView="parm4" Condition="NumParams==4"></DisplayString>
+ <DisplayString IncludeView="parm4">, {*((clang::QualType *)(this+1)+4),view(cpp)}{*this,view(parm5)}</DisplayString>
+ <DisplayString IncludeView="parm5" Condition="NumParams==5"></DisplayString>
+ <DisplayString IncludeView="parm5">, /* expand for more params */</DisplayString>
+ <DisplayString>{*this,view(retType)}({*this,view(parm0)})</DisplayString>
+ <Expand>
+ <Item Name="ReturnType">ResultType</Item>
+ <Synthetic Name="Parameter Types">
+ <DisplayString>{*this,view(parm0)}</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>NumParams</Size>
+ <ValuePointer>(clang::QualType *)(this+1)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Synthetic>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::TemplateTypeParmType">
+ <DisplayString IncludeView="cpp">{*TTPDecl,view(cpp)}</DisplayString>
+ <DisplayString>{*TTPDecl}</DisplayString>
+ </Type>
+ <Type Name="clang::InjectedClassNameType">
+ <DisplayString>{*Decl,view(cpp)}</DisplayString>
+ <Expand>
+ <Item Name="Decl">Decl</Item>
+ <Item Name="InjectedType">InjectedType</Item>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::PackExpansionType">
+ <DisplayString>{Pattern}</DisplayString>
+ <Expand>
+ <Item Name="Pattern">Pattern</Item>
+ <Item Name="NumExpansions">NumExpansions</Item>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::QualType">
+ <!-- When VS2013 support is deprecated, change 4 to clang::TypeAlignmentInBits (not properly recognized by VS2013) -->
+ <DisplayString IncludeView="poly">{*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) &amp; ~(uintptr_t)((1 &lt;&lt; 4) - 1)))-&gt;BaseType,view(poly)}{*this,view(fastQuals)}</DisplayString>
+ <DisplayString IncludeView="cpp">{*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) &amp; ~(uintptr_t)((1 &lt;&lt; 4) - 1)))-&gt;BaseType,view(cpp)}{*this,view(fastQuals)}</DisplayString>
+ <!-- For the Fast Qualifiers, it is simpler (and probably more efficient) just to list all 8 cases than create
+ views for each qualifier. TODO: Non-fast qualifiers -->
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==0"></DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==1">{" ",sb}const</DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==2">{" ",sb}restrict</DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==3">{" ",sb}const restrict</DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==4">{" ",sb}volatile</DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==5">{" ",sb}const volatile</DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==6">{" ",sb}volatile restrict</DisplayString>
+ <DisplayString IncludeView="fastQuals" Condition="(Value.Value &amp; 15)==7">{" ",sb}const volatile restrict</DisplayString>
+ <DisplayString IncludeView="fastQuals">Cannot visualize non-fast qualifiers</DisplayString>
+ <DisplayString>{*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) &amp; ~(uintptr_t)((1 &lt;&lt; 4) - 1)))-&gt;BaseType}{*this,view(fastQuals)}</DisplayString>
+ <Expand>
+ <Item Name="Fast Quals">*this,view(fastQuals)</Item>
+ <Item Name="BaseType">*((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) &amp; ~(uintptr_t)((1 &lt;&lt; 4) - 1)))-&gt;BaseType</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::LocInfoType">
+ <DisplayString>{*DeclInfo}</DisplayString>
+ <Expand>
+ <Item Name="DeclInfo">DeclInfo</Item>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::TypeSourceInfo">
+ <DisplayString>{Ty}</DisplayString>
+ </Type>
+ <Type Name="clang::TemplateArgumentLoc">
+ <DisplayString>{Argument}</DisplayString>
+ <Expand>
+ <ExpandedItem>Argument</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::TemplateArgument">
+ <DisplayString IncludeView="cpp" Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Type">{*(clang::QualType *)&amp;TypeOrValue.V,view(cpp)}</DisplayString>
+ <DisplayString Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Type">{(clang::TemplateArgument::ArgKind)TypeOrValue.Kind,en} template argument: {*(clang::QualType *)&amp;TypeOrValue.V}</DisplayString>
+ <DisplayString IncludeView="arg0" Condition="Args.NumArgs==0"></DisplayString>
+ <DisplayString IncludeView="arg0">{Args.Args[0]}{*this,view(arg1)}</DisplayString>
+ <DisplayString IncludeView="arg1" Condition="Args.NumArgs==1"></DisplayString>
+ <DisplayString IncludeView="arg1">, {Args.Args[1]}{*this,view(arg2)}</DisplayString>
+ <DisplayString IncludeView="arg2" Condition="Args.NumArgs==2"></DisplayString>
+ <DisplayString IncludeView="arg2">, {Args.Args[2]}, ...</DisplayString>
+ <DisplayString IncludeView="arg0cpp" Condition="Args.NumArgs==0"></DisplayString>
+ <DisplayString IncludeView="arg0cpp">{Args.Args[0],view(cpp)}{*this,view(arg1cpp)}</DisplayString>
+ <DisplayString IncludeView="arg1cpp" Condition="Args.NumArgs==1"></DisplayString>
+ <DisplayString IncludeView="arg1cpp">, {Args.Args[1],view(cpp)}{*this,view(arg2cpp)}</DisplayString>
+ <DisplayString IncludeView="arg2cpp" Condition="Args.NumArgs==2"></DisplayString>
+ <DisplayString IncludeView="arg2cpp">, {Args.Args[2],view(cpp)}, ...</DisplayString>
+ <DisplayString IncludeView="cpp" Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Pack">{*this,view(arg0cpp)}</DisplayString>
+ <DisplayString Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Pack">{*this,view(arg0)}</DisplayString>
+ <DisplayString>{(clang::TemplateArgument::ArgKind)TypeOrValue.Kind,en}</DisplayString>
+ <Expand>
+ <Item Name="QualType" Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Type">*(clang::QualType *)&amp;TypeOrValue.V</Item>
+ <ArrayItems Condition="Integer.Kind == clang::TemplateArgument::ArgKind::Pack">
+ <Size>Args.NumArgs</Size>
+ <ValuePointer>Args.Args</ValuePointer>
+ </ArrayItems>
+ <!-- TODO: Other kinds-->
+ </Expand>
+ </Type>
+ <Type Name="clang::TemplateArgumentList">
+ <DisplayString IncludeView="arg0" Condition="NumArguments==0"></DisplayString>
+ <DisplayString IncludeView="arg0">{Arguments[0],view(cpp)}{*this,view(arg1)}</DisplayString>
+ <DisplayString IncludeView="arg1" Condition="NumArguments==1"></DisplayString>
+ <DisplayString IncludeView="arg1">, {Arguments[1],view(cpp)}{*this,view(arg2)}</DisplayString>
+ <DisplayString IncludeView="arg2" Condition="NumArguments==2"></DisplayString>
+ <DisplayString IncludeView="arg2">, {Arguments[1],view(cpp)}, ...</DisplayString>
+ <DisplayString>&lt;{*this,view(arg0)}&gt;</DisplayString>
+ <Expand>
+ <Item Name="NumArguments">NumArguments</Item>
+ <ArrayItems>
+ <Size>NumArguments</Size>
+ <ValuePointer>Arguments</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+ <Type Name="llvm::ArrayRef&lt;clang::TemplateArgument&gt;">
+ <DisplayString IncludeView="arg0" Condition="Length==0"></DisplayString>
+ <DisplayString IncludeView="arg0">{Data[0],view(cpp)}{*this,view(arg1)}</DisplayString>
+ <DisplayString IncludeView="arg1" Condition="Length==1"></DisplayString>
+ <DisplayString IncludeView="arg1">, {Data[1],view(cpp)}{*this,view(arg2)}</DisplayString>
+ <DisplayString IncludeView="arg2" Condition="Length==2"></DisplayString>
+ <DisplayString IncludeView="arg2">, {Data[2],view(cpp)}, ...</DisplayString>
+ <DisplayString>&lt;{*this,view(arg0)}&gt;</DisplayString>
+ </Type>
+ <Type Name="clang::MultiLevelTemplateArgumentList">
+ <DisplayString IncludeView="level0" Condition="(llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.EndX - (llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.BeginX==0"></DisplayString>
+ <DisplayString IncludeView="level0">{((llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.BeginX)[0],view(cpp)}{*this,view(level1)}</DisplayString>
+ <DisplayString IncludeView="level1" Condition="(llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.EndX - (llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.BeginX==1"></DisplayString>
+ <DisplayString IncludeView="level1">::{((llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.BeginX)[1],view(cpp)}{*this,view(level2)}</DisplayString>
+ <DisplayString IncludeView="level2" Condition="(llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.EndX - (llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.BeginX==2"></DisplayString>
+ <DisplayString IncludeView="level2">::{((llvm::ArrayRef&lt;clang::TemplateArgument&gt; *)TemplateArgumentLists.BeginX)[2],view(cpp)}, ...</DisplayString>
+ <DisplayString>{*this,view(level0)}</DisplayString>
+ <Expand>
+ <Item Name="TemplateList">TemplateArgumentLists</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::ParsedTemplateArgument">
+ <DisplayString Condition="Kind==clang::ParsedTemplateArgument::Type">Type template argument: {*(clang::QualType *)Arg}</DisplayString>
+ <DisplayString Condition="Kind==clang::ParsedTemplateArgument::NonType">Non-type template argument: {*(clang::Expr *)Arg}</DisplayString>
+ <DisplayString Condition="Kind==clang::ParsedTemplateArgument::Template">Template template argument: {*(clang::TemplateName *)Arg</DisplayString>
+ <Expand>
+ <Item Name="Kind">Kind,en</Item>
+ <Item Name="Arg" Condition="Kind==clang::ParsedTemplateArgument::Type">(clang::QualType *)Arg</Item>
+ <Item Name="Arg" Condition="Kind==clang::ParsedTemplateArgument::NonType">(clang::Expr *)Arg</Item>
+ <Item Name="Arg" Condition="Kind==clang::ParsedTemplateArgument::Template">(clang::TemplateName *)Arg</Item>
+ </Expand>
+ </Type>
+ <!-- Builtin types that have C++ keywords are manually displayed as that keyword. Otherwise, just use the enum name -->
+ <Type Name="clang::BuiltinType">
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Void">void</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Bool">bool</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char_U">char</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UChar">unsigned char</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::WChar_U">wchar_t</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char16">char16_t</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char32">char32_t</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UShort">unsigned short</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UInt">unsigned int</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::ULong">unsigned long</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::ULongLong">unsigned long long</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::UInt128">__uint128_t</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Char_S">char</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::SChar">signed char</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::WChar_S">wchar_t</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Short">short</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Int">int</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Long">long</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::LongLong">long long</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Int128">__int128_t</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Half">__fp16</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Float">float</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::Double">double</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::LongDouble">long double</DisplayString>
+ <DisplayString Condition="BuiltinTypeBits.Kind==clang::BuiltinType::NullPtr">nullptr_t</DisplayString>
+ <DisplayString>{(clang::BuiltinType::Kind)BuiltinTypeBits.Kind, en}</DisplayString>
+ <Expand>
+ <Item Name="Kind">(clang::BuiltinType::Kind)BuiltinTypeBits.Kind</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="clang::TemplateSpecializationType">
+ <DisplayString IncludeView="arg0" Condition="NumArgs==0"></DisplayString>
+ <DisplayString IncludeView="arg0">{((clang::TemplateArgument *)(this+1))[0],view(cpp)}{*this,view(arg1)}</DisplayString>
+ <DisplayString IncludeView="arg1" Condition="NumArgs==1"></DisplayString>
+ <DisplayString IncludeView="arg1">, {((clang::TemplateArgument *)(this+1))[1],view(cpp)}{*this,view(arg2)}</DisplayString>
+ <DisplayString IncludeView="arg2" Condition="NumArgs==2"></DisplayString>
+ <DisplayString IncludeView="arg2">, {((clang::TemplateArgument *)(this+1))[2],view(cpp)}{*this,view(arg3)}</DisplayString>
+ <DisplayString Condition="(Template.Storage.Val.Val.Value &amp; 3) == 0">
+ {*((clang::TemplateDecl *)((Template.Storage.Val.Val.Value &gt;&gt; 2) &lt;&lt; 2))->TemplatedDecl,view(cpp)}&lt;{*this,view(arg0)}&gt;
+ </DisplayString>
+ <Expand>
+ <Item Name="Template">Template.Storage</Item>
+ <ArrayItems>
+ <Size>NumArgs</Size>
+ <ValuePointer>(clang::TemplateArgument *)(this+1)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+ <Type Name="clang::IdentifierInfo">
+ <DisplayString Condition="Entry != 0">{((llvm::StringMapEntry&lt;clang::IdentifierInfo *&gt;*)Entry)+1,sb}</DisplayString>
+ <Expand>
+ <Item Condition="Entry != 0" Name="[Identifier]">((llvm::StringMapEntry&lt;clang::IdentifierInfo *&gt;*)Entry)+1,s</Item>
+ <Item Name="Token Kind">(clang::tok::TokenKind)TokenID</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::DeclarationName">
+ <DisplayString Condition="Ptr == 0" IncludeView="cpp"></DisplayString>
+ <DisplayString Condition="Ptr == 0">Empty</DisplayString>
+ <DisplayString Condition="(Ptr &amp; PtrMask) == StoredIdentifier" IncludeView="cpp">{*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)}</DisplayString>
+ <DisplayString Condition="(Ptr &amp; PtrMask) == StoredIdentifier">{{Identifier ({*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>
+ <DisplayString Condition="(Ptr &amp; PtrMask) == StoredObjCZeroArgSelector">{{ObjC Zero Arg Selector (*{(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>
+ <DisplayString Condition="(Ptr &amp; PtrMask) == StoredObjCOneArgSelector">{{ObjC One Arg Selector (*{(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)})}}</DisplayString>
+ <DisplayString Condition="(Ptr &amp; PtrMask) == StoredDeclarationNameExtra"
+ IncludeView="cpp">{*(clang::DeclarationNameExtra *)(Ptr &amp; ~PtrMask),view(cpp)}</DisplayString>
+ <DisplayString Condition="(Ptr &amp; PtrMask) == StoredDeclarationNameExtra">{{Extra ({*(clang::DeclarationNameExtra *)(Ptr &amp; ~PtrMask)})}}</DisplayString>
+ <Expand>
+ <Item Condition="(Ptr &amp; PtrMask) == StoredIdentifier" Name="[Identifier]">*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>
+ <Item Condition="(Ptr &amp; PtrMask) == StoredObjCZeroArgSelector" Name="[ObjC Zero Arg Selector]">*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>
+ <Item Condition="(Ptr &amp; PtrMask) == StoredObjCOneArgSelector" Name="[ObjC One Arg Selector]">*(clang::IdentifierInfo *)(Ptr &amp; ~PtrMask)</Item>
+ <Item Condition="(Ptr &amp; PtrMask) == StoredDeclarationNameExtra" Name="[Extra]">(clang::DeclarationNameExtra *)(Ptr &amp; ~PtrMask)</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::DeclarationNameExtra">
+ <DisplayString IncludeView="cpp"
+ Condition="ExtraKindOrNumArgs &gt;= clang::DeclarationNameExtra::CXXConstructor
+ &amp;&amp; ExtraKindOrNumArgs &lt;= clang::DeclarationNameExtra::CXXConversionFunction"
+ >{((clang::CXXSpecialName *)this)-&gt;Type,view(cpp)}</DisplayString>
+ <DisplayString>{(clang::DeclarationNameExtra::ExtraKind)ExtraKindOrNumArgs,en}{" ",sb}{*this,view(cpp)}</DisplayString>
+ </Type>
+ <Type Name="clang::Token">
+ <DisplayString Condition="Kind != clang::tok::identifier">{(clang::tok::TokenKind)Kind,en}</DisplayString>
+ <DisplayString Condition="Kind == clang::tok::identifier">{{Identifier ({*(clang::IdentifierInfo *)(PtrData)})}}</DisplayString>
+ </Type>
+ <Type Name="clang::DeclSpec">
+ <DisplayString>[{(clang::DeclSpec::SCS)StorageClassSpec}], [{(clang::TypeSpecifierType)TypeSpecType}]</DisplayString>
+ </Type>
+ <Type Name="clang::PragmaHandler">
+ <DisplayString>{Name,s}</DisplayString>
+ </Type>
+ <Type Name="clang::FileEntry">
+ <DisplayString>{Name,s}</DisplayString>
+ </Type>
+ <Type Name="clang::DirectoryEntry">
+ <DisplayString>{Name,s}</DisplayString>
+ </Type>
+ <Type Name="clang::VarDecl::VarDeclBitfields">
+ <Expand>
+ <Item Name="StorageClass">(clang::StorageClass)SClass</Item>
+ <Item Name="ThreadStorageClass">(clang::ThreadStorageClassSpecifier)TSCSpec</Item>
+ <Item Name="InitStyle">(clang::VarDecl::InitializationStyle)InitStyle</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::DeclaratorDecl">
+ <DisplayString>{DeclType,view(cpp)} {Name,view(cpp)}</DisplayString>
+ <Expand>
+ <Item Name="Name">Name</Item>
+ <Item Name="DeclType">DeclType</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::VarDecl">
+ <DisplayString>{*(DeclaratorDecl*)this,nd}</DisplayString>
+ <Expand>
+ <ExpandedItem>*(DeclaratorDecl*)this,nd</ExpandedItem>
+ <Item Name="VarDeclBits">VarDeclBits</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::ParmVarDecl">
+ <DisplayString>{*(VarDecl*)this,nd}</DisplayString>
+ <Expand>
+ <Item Name="ParmVarDeclBits">ParmVarDeclBits</Item>
+ <ExpandedItem>*(VarDecl*)this,nd</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::FunctionDecl">
+ <DisplayString IncludeView="retType">{*(clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType,view(retType)}</DisplayString>
+ <DisplayString IncludeView="parm0" Condition="0 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams"></DisplayString>
+ <DisplayString IncludeView="parm0">{*ParamInfo[0]}{*this,view(parm1)nd}</DisplayString>
+ <DisplayString IncludeView="parm1" Condition="1 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams"></DisplayString>
+ <DisplayString IncludeView="parm1">, {*ParamInfo[1]}{*this,view(parm2)nd}</DisplayString>
+ <DisplayString IncludeView="parm2" Condition="2 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams"></DisplayString>
+ <DisplayString IncludeView="parm2">, {*ParamInfo[2]}{*this,view(parm3)nd}</DisplayString>
+ <DisplayString IncludeView="parm3" Condition="3 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams"></DisplayString>
+ <DisplayString IncludeView="parm3">, {*ParamInfo[3]}{*this,view(parm4)nd}</DisplayString>
+ <DisplayString IncludeView="parm4" Condition="4 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams"></DisplayString>
+ <DisplayString IncludeView="parm4">, {*ParamInfo[4]}{*this,view(parm5)nd}</DisplayString>
+ <DisplayString IncludeView="parm5" Condition="5 == ((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams"></DisplayString>
+ <DisplayString IncludeView="parm5">, /* expand for more params */</DisplayString>
+ <DisplayString>{*this,view(retType)nd} {Name,view(cpp)nd}({*this,view(parm0)nd})</DisplayString>
+ <Expand>
+ <Item Name="ReturnType">*this,view(retType)nd</Item>
+ <Synthetic Name="Parameter Types">
+ <DisplayString>{*this,view(parm0)nd}</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>((clang::FunctionProtoType *)((clang::ExtQualsTypeCommonBase *)(((uintptr_t)DeclType.Value.Value) &amp; ~15))-&gt;BaseType)-&gt;NumParams</Size>
+ <ValuePointer>ParamInfo</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Synthetic>
+ <ExpandedItem>*(clang::Type *)this, view(cmn)</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::OpaquePtr&lt;clang::QualType&gt;">
+ <DisplayString>{*(clang::QualType *)this}</DisplayString>
+ <Expand>
+ <Item Name="Ptr">*(clang::QualType *)this</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::UnionOpaquePtr&lt;clang::QualType&gt;">
+ <DisplayString>{*(clang::QualType *)this}</DisplayString>
+ <Expand>
+ <Item Name="Ptr">*(clang::QualType *)this</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::OpaquePtr&lt;*&gt;">
+ <DisplayString>{($T1 *)Ptr}</DisplayString>
+ <Expand>
+ <ExpandedItem>($T1 *)Ptr</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::UnionOpaquePtr&lt;*&gt;">
+ <DisplayString>{($T1 *)Ptr}</DisplayString>
+ <Expand>
+ <ExpandedItem>($T1 *)Ptr</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::TemplateParameterList">
+ <DisplayString IncludeView="parm0" Condition="NumParams==0"></DisplayString>
+ <DisplayString IncludeView="parm0">{*((NamedDecl **)(this+1))[0],view(cpp)}{*this,view(parm1)}</DisplayString>
+ <DisplayString IncludeView="parm1" Condition="NumParams==1"></DisplayString>
+ <DisplayString IncludeView="parm1">, {*((NamedDecl **)(this+1))[1],view(cpp)}{*this,view(parm2)}</DisplayString>
+ <DisplayString IncludeView="parm2" Condition="NumParams==2"></DisplayString>
+ <DisplayString IncludeView="parm2">, {*((NamedDecl **)(this+1))[2],view(cpp)}{*this,view(parm3)}</DisplayString>
+ <DisplayString IncludeView="parm3" Condition="NumParams==3"></DisplayString>
+ <DisplayString IncludeView="parm3">, {*((NamedDecl **)(this+1))[3],view(cpp)}{*this,view(parm4)}</DisplayString>
+ <DisplayString IncludeView="parm4" Condition="NumParams==4"></DisplayString>
+ <DisplayString IncludeView="parm4">, {*((NamedDecl **)(this+1))[4],view(cpp)}{*this,view(parm5)}</DisplayString>
+ <DisplayString IncludeView="parm5" Condition="NumParams==5"></DisplayString>
+ <DisplayString IncludeView="parm5">, /* Expand for more params */</DisplayString>
+ <DisplayString>&lt;{*this,view(parm0)}&gt;</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>NumParams</Size>
+ <ValuePointer>(NamedDecl **)(this+1)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+ <Type Name="clang::Stmt">
+ <DisplayString>{(clang::Stmt::StmtClass)StmtBits.sClass,en}</DisplayString>
+ <Expand>
+ <Item Name="Class">(clang::Stmt::StmtClass)StmtBits.sClass,en</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::Expr">
+ <DisplayString>Expression of class {(clang::Stmt::StmtClass)StmtBits.sClass,en} and type {TR,view(cpp)}</DisplayString>
+ </Type>
+ <Type Name="clang::DeclAccessPair">
+ <DisplayString IncludeView="access" Condition="(Ptr&amp;Mask) == clang::AS_public">public</DisplayString>
+ <DisplayString IncludeView="access" Condition="(Ptr&amp;Mask) == clang::AS_protected">protected</DisplayString>
+ <DisplayString IncludeView="access" Condition="(Ptr&amp;Mask) == clang::AS_private">private</DisplayString>
+ <DisplayString IncludeView="access" Condition="(Ptr&amp;Mask) == clang::AS_none">b</DisplayString>
+ <DisplayString IncludeView="decl">{*(clang::NamedDecl *)(Ptr&amp;~Mask)}</DisplayString>
+ <DisplayString>{*this,view(access)} {*this,view(decl)}</DisplayString>
+ </Type>
+ <Type Name="clang::UnresolvedSet&lt;*&gt;">
+ <DisplayString>{Decls}</DisplayString>
+ <Expand>
+ <ExpandedItem>Decls</ExpandedItem>
+ </Expand>
+ </Type>
+ <Type Name="clang::LookupResult">
+ <DisplayString Condition="ResultKind == clang::LookupResult::Ambiguous">{Ambiguity,en}: {Decls}</DisplayString>
+ <DisplayString>{ResultKind,en}: {Decls}</DisplayString>
+ </Type>
+ <Type Name="clang::ActionResult&lt;*&gt;" IncludeView="packedValidity">
+ <DisplayString Condition="PtrWithInvalid&amp;1">Invalid</DisplayString>
+ <DisplayString Condition="!(PtrWithInvalid&amp;1)">Valid</DisplayString>
+ </Type>
+ <Type Name="clang::ActionResult&lt;*&gt;" IncludeView="unpackedValidity">
+ <DisplayString Condition="Invalid">Invalid</DisplayString>
+ <DisplayString Condition="!Invalid">Valid</DisplayString>
+ </Type>
+ <Type Name="clang::ActionResult&lt;*&gt;" IncludeView="packed">
+ <DisplayString>{*this,view(packedValidity)}: {($T1 *)(PtrWithInvalid&amp;~1)}</DisplayString>
+ <Expand>
+ <Item Name="Invalid">(bool)(PtrWithInvalid&amp;1)</Item>
+ <Item Name="Val">($T1 *)(PtrWithInvalid&amp;~1)</Item>
+ </Expand>
+ </Type>
+ <Type Name="clang::ActionResult&lt;*&gt;" IncludeView="unpacked">
+ <DisplayString>{*this,view(unpackedValidity)}: {Val}</DisplayString>
+ </Type>
+ <Type Name="clang::ActionResult&lt;*&gt;">
+ <DisplayString Condition="$T2">{*this,view(packed)}</DisplayString>
+ <DisplayString Condition="!$T2">{*this,view(unpacked)}</DisplayString>
+ <Expand>
+ <ExpandedItem Condition="$T2">*this,view(packed)</ExpandedItem>
+ <ExpandedItem Condition="!$T2">*this,view(unpacked)</ExpandedItem>
+ </Expand>
+ </Type>
+</AutoVisualizer>
diff --git a/gnu/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp b/gnu/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
index f70bff2c3b7..50102af33a5 100644
--- a/gnu/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/gnu/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -11,24 +11,36 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
+#include <cassert>
#include <cctype>
+#include <cstddef>
+#include <cstdint>
+#include <map>
#include <memory>
#include <set>
#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
using namespace llvm;
namespace {
+
class FlattenedSpelling {
std::string V, N, NS;
bool K;
@@ -54,6 +66,7 @@ public:
const std::string &nameSpace() const { return NS; }
bool knownToGCC() const { return K; }
};
+
} // end anonymous namespace
static std::vector<FlattenedSpelling>
@@ -81,22 +94,26 @@ static std::string ReadPCHRecord(StringRef type) {
.Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)")
.Case("Expr *", "ReadExpr(F)")
.Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
- .Case("std::string", "ReadString(Record, Idx)")
+ .Case("StringRef", "ReadString(Record, Idx)")
.Default("Record[Idx++]");
}
+// Get a type that is suitable for storing an object of the specified type.
+static StringRef getStorageType(StringRef type) {
+ return StringSwitch<StringRef>(type)
+ .Case("StringRef", "std::string")
+ .Default(type);
+}
+
// Assumes that the way to get the value is SA->getname()
static std::string WritePCHRecord(StringRef type, StringRef name) {
- return StringSwitch<std::string>(type)
- .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
- ", Record);\n")
- .Case("TypeSourceInfo *",
- "AddTypeSourceInfo(" + std::string(name) + ", Record);\n")
+ return "Record." + StringSwitch<std::string>(type)
+ .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + ");\n")
+ .Case("TypeSourceInfo *", "AddTypeSourceInfo(" + std::string(name) + ");\n")
.Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
- .Case("IdentifierInfo *",
- "AddIdentifierRef(" + std::string(name) + ", Record);\n")
- .Case("std::string", "AddString(" + std::string(name) + ", Record);\n")
- .Default("Record.push_back(" + std::string(name) + ");\n");
+ .Case("IdentifierInfo *", "AddIdentifierRef(" + std::string(name) + ");\n")
+ .Case("StringRef", "AddString(" + std::string(name) + ");\n")
+ .Default("push_back(" + std::string(name) + ");\n");
}
// Normalize attribute name by removing leading and trailing
@@ -162,6 +179,7 @@ static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
}
namespace {
+
class Argument {
std::string lowerName, upperName;
StringRef attrName;
@@ -176,6 +194,11 @@ namespace {
lowerName[0] = std::tolower(lowerName[0]);
upperName[0] = std::toupper(upperName[0]);
}
+ // Work around MinGW's macro definition of 'interface' to 'struct'. We
+ // have an attribute argument called 'Interface', so only the lower case
+ // name conflicts with the macro definition.
+ if (lowerName == "interface")
+ lowerName = "interface_";
}
virtual ~Argument() = default;
@@ -223,8 +246,7 @@ namespace {
public:
SimpleArgument(const Record &Arg, StringRef Attr, std::string T)
- : Argument(Arg, Attr), type(T)
- {}
+ : Argument(Arg, Attr), type(std::move(T)) {}
std::string getType() const { return type; }
@@ -233,35 +255,45 @@ namespace {
OS << " return " << getLowerName() << ";\n";
OS << " }";
}
+
void writeCloneArgs(raw_ostream &OS) const override {
OS << getLowerName();
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
OS << "A->get" << getUpperName() << "()";
}
+
void writeCtorInitializers(raw_ostream &OS) const override {
OS << getLowerName() << "(" << getUpperName() << ")";
}
+
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
OS << getLowerName() << "()";
}
+
void writeCtorParameters(raw_ostream &OS) const override {
OS << type << " " << getUpperName();
}
+
void writeDeclarations(raw_ostream &OS) const override {
OS << type << " " << getLowerName() << ";";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
std::string read = ReadPCHRecord(type);
OS << " " << type << " " << getLowerName() << " = " << read << ";\n";
}
+
void writePCHReadArgs(raw_ostream &OS) const override {
OS << getLowerName();
}
+
void writePCHWrite(raw_ostream &OS) const override {
OS << " " << WritePCHRecord(type, "SA->get" +
std::string(getUpperName()) + "()");
}
+
void writeValue(raw_ostream &OS) const override {
if (type == "FunctionDecl *") {
OS << "\" << get" << getUpperName()
@@ -274,6 +306,7 @@ namespace {
OS << "\" << get" << getUpperName() << "() << \"";
}
}
+
void writeDump(raw_ostream &OS) const override {
if (type == "FunctionDecl *") {
OS << " OS << \" \";\n";
@@ -309,7 +342,12 @@ namespace {
SimpleArgument::writeAccessors(OS);
OS << "\n\n static const " << getType() << " Default" << getUpperName()
- << " = " << Default << ";";
+ << " = ";
+ if (getType() == "bool")
+ OS << (Default != 0 ? "true" : "false");
+ else
+ OS << Default;
+ OS << ";";
}
};
@@ -337,45 +375,57 @@ namespace {
<< getLowerName() << "Length);\n";
OS << " }";
}
+
void writeCloneArgs(raw_ostream &OS) const override {
OS << "get" << getUpperName() << "()";
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
OS << "A->get" << getUpperName() << "()";
}
+
void writeCtorBody(raw_ostream &OS) const override {
OS << " if (!" << getUpperName() << ".empty())\n";
OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
- << ".data(), " << getLowerName() << "Length);";
+ << ".data(), " << getLowerName() << "Length);\n";
}
+
void writeCtorInitializers(raw_ostream &OS) const override {
OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
<< getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
<< "Length])";
}
+
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
OS << getLowerName() << "Length(0)," << getLowerName() << "(nullptr)";
}
+
void writeCtorParameters(raw_ostream &OS) const override {
OS << "llvm::StringRef " << getUpperName();
}
+
void writeDeclarations(raw_ostream &OS) const override {
OS << "unsigned " << getLowerName() << "Length;\n";
OS << "char *" << getLowerName() << ";";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
OS << " std::string " << getLowerName()
<< "= ReadString(Record, Idx);\n";
}
+
void writePCHReadArgs(raw_ostream &OS) const override {
OS << getLowerName();
}
+
void writePCHWrite(raw_ostream &OS) const override {
- OS << " AddString(SA->get" << getUpperName() << "(), Record);\n";
+ OS << " Record.AddString(SA->get" << getUpperName() << "());\n";
}
+
void writeValue(raw_ostream &OS) const override {
OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
}
+
void writeDump(raw_ostream &OS) const override {
OS << " OS << \" \\\"\" << SA->get" << getUpperName()
<< "() << \"\\\"\";\n";
@@ -407,6 +457,7 @@ namespace {
OS << " return " << getLowerName() << "Type;\n";
OS << " }";
}
+
void writeAccessorDefinitions(raw_ostream &OS) const override {
OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
<< "Dependent() const {\n";
@@ -434,16 +485,19 @@ namespace {
OS << " return 0; // FIXME\n";
OS << "}\n";
}
+
void writeCloneArgs(raw_ostream &OS) const override {
OS << "is" << getLowerName() << "Expr, is" << getLowerName()
<< "Expr ? static_cast<void*>(" << getLowerName()
<< "Expr) : " << getLowerName()
<< "Type";
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
// FIXME: move the definition in Sema::InstantiateAttrs to here.
// In the meantime, aligned attributes are cloned.
}
+
void writeCtorBody(raw_ostream &OS) const override {
OS << " if (is" << getLowerName() << "Expr)\n";
OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
@@ -451,20 +505,25 @@ namespace {
OS << " else\n";
OS << " " << getLowerName()
<< "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
- << ");";
+ << ");\n";
}
+
void writeCtorInitializers(raw_ostream &OS) const override {
OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
}
+
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
OS << "is" << getLowerName() << "Expr(false)";
}
+
void writeCtorParameters(raw_ostream &OS) const override {
OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
}
+
void writeImplicitCtorArgs(raw_ostream &OS) const override {
OS << "Is" << getUpperName() << "Expr, " << getUpperName();
}
+
void writeDeclarations(raw_ostream &OS) const override {
OS << "bool is" << getLowerName() << "Expr;\n";
OS << "union {\n";
@@ -472,9 +531,11 @@ namespace {
OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
OS << "};";
}
+
void writePCHReadArgs(raw_ostream &OS) const override {
OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n";
OS << " void *" << getLowerName() << "Ptr;\n";
@@ -484,14 +545,16 @@ namespace {
OS << " " << getLowerName()
<< "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
}
+
void writePCHWrite(raw_ostream &OS) const override {
OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
OS << " if (SA->is" << getUpperName() << "Expr())\n";
- OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n";
+ OS << " Record.AddStmt(SA->get" << getUpperName() << "Expr());\n";
OS << " else\n";
- OS << " AddTypeSourceInfo(SA->get" << getUpperName()
- << "Type(), Record);\n";
+ OS << " Record.AddTypeSourceInfo(SA->get" << getUpperName()
+ << "Type());\n";
}
+
void writeValue(raw_ostream &OS) const override {
OS << "\";\n";
// The aligned attribute argument expression is optional.
@@ -500,8 +563,9 @@ namespace {
OS << " " << getLowerName() << "Expr->printPretty(OS, nullptr, Policy);\n";
OS << " OS << \"";
}
- void writeDump(raw_ostream &OS) const override {
- }
+
+ void writeDump(raw_ostream &OS) const override {}
+
void writeDumpChildren(raw_ostream &OS) const override {
OS << " if (SA->is" << getUpperName() << "Expr())\n";
OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n";
@@ -509,6 +573,7 @@ namespace {
OS << " dumpType(SA->get" << getUpperName()
<< "Type()->getType());\n";
}
+
void writeHasChildren(raw_ostream &OS) const override {
OS << "SA->is" << getUpperName() << "Expr()";
}
@@ -525,10 +590,13 @@ namespace {
public:
VariadicArgument(const Record &Arg, StringRef Attr, std::string T)
- : Argument(Arg, Attr), Type(T), ArgName(getLowerName().str() + "_"),
- ArgSizeName(ArgName + "Size"), RangeName(getLowerName()) {}
+ : Argument(Arg, Attr), Type(std::move(T)),
+ ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"),
+ RangeName(getLowerName()) {}
- std::string getType() const { return Type; }
+ const std::string &getType() const { return Type; }
+ const std::string &getArgName() const { return ArgName; }
+ const std::string &getArgSizeName() const { return ArgSizeName; }
bool isVariadic() const override { return true; }
void writeAccessors(raw_ostream &OS) const override {
@@ -547,56 +615,87 @@ namespace {
<< "() const { return llvm::make_range(" << BeginFn << ", " << EndFn
<< "); }\n";
}
+
void writeCloneArgs(raw_ostream &OS) const override {
OS << ArgName << ", " << ArgSizeName;
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
// This isn't elegant, but we have to go through public methods...
OS << "A->" << getLowerName() << "_begin(), "
<< "A->" << getLowerName() << "_size()";
}
+
void writeCtorBody(raw_ostream &OS) const override {
OS << " std::copy(" << getUpperName() << ", " << getUpperName()
- << " + " << ArgSizeName << ", " << ArgName << ");";
+ << " + " << ArgSizeName << ", " << ArgName << ");\n";
}
+
void writeCtorInitializers(raw_ostream &OS) const override {
OS << ArgSizeName << "(" << getUpperName() << "Size), "
<< ArgName << "(new (Ctx, 16) " << getType() << "["
<< ArgSizeName << "])";
}
+
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
OS << ArgSizeName << "(0), " << ArgName << "(nullptr)";
}
+
void writeCtorParameters(raw_ostream &OS) const override {
OS << getType() << " *" << getUpperName() << ", unsigned "
<< getUpperName() << "Size";
}
+
void writeImplicitCtorArgs(raw_ostream &OS) const override {
OS << getUpperName() << ", " << getUpperName() << "Size";
}
+
void writeDeclarations(raw_ostream &OS) const override {
OS << " unsigned " << ArgSizeName << ";\n";
OS << " " << getType() << " *" << ArgName << ";";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
- OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
- OS << " SmallVector<" << Type << ", 4> " << getLowerName()
- << ";\n";
- OS << " " << getLowerName() << ".reserve(" << getLowerName()
+ OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
+ OS << " SmallVector<" << getType() << ", 4> "
+ << getLowerName() << ";\n";
+ OS << " " << getLowerName() << ".reserve(" << getLowerName()
<< "Size);\n";
- OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
-
+
+ // If we can't store the values in the current type (if it's something
+ // like StringRef), store them in a different type and convert the
+ // container afterwards.
+ std::string StorageType = getStorageType(getType());
+ std::string StorageName = getLowerName();
+ if (StorageType != getType()) {
+ StorageName += "Storage";
+ OS << " SmallVector<" << StorageType << ", 4> "
+ << StorageName << ";\n";
+ OS << " " << StorageName << ".reserve(" << getLowerName()
+ << "Size);\n";
+ }
+
+ OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
std::string read = ReadPCHRecord(Type);
- OS << " " << getLowerName() << ".push_back(" << read << ");\n";
+ OS << " " << StorageName << ".push_back(" << read << ");\n";
+
+ if (StorageType != getType()) {
+ OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
+ OS << " " << getLowerName() << ".push_back("
+ << StorageName << "[i]);\n";
+ }
}
+
void writePCHReadArgs(raw_ostream &OS) const override {
OS << getLowerName() << ".data(), " << getLowerName() << "Size";
}
+
void writePCHWrite(raw_ostream &OS) const override {
OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
OS << " for (auto &Val : SA->" << RangeName << "())\n";
OS << " " << WritePCHRecord(Type, "Val");
}
+
void writeValue(raw_ostream &OS) const override {
OS << "\";\n";
OS << " bool isFirst = true;\n"
@@ -607,6 +706,7 @@ namespace {
OS << " }\n";
OS << " OS << \"";
}
+
void writeDump(raw_ostream &OS) const override {
OS << " for (const auto &Val : SA->" << RangeName << "())\n";
OS << " OS << \" \" << Val;\n";
@@ -649,9 +749,11 @@ namespace {
OS << " return " << getLowerName() << ";\n";
OS << " }";
}
+
void writeCloneArgs(raw_ostream &OS) const override {
OS << getLowerName();
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
OS << "A->get" << getUpperName() << "()";
}
@@ -678,17 +780,21 @@ namespace {
OS << "private:\n";
OS << " " << type << " " << getLowerName() << ";";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName()
<< "(static_cast<" << getAttrName() << "Attr::" << type
<< ">(Record[Idx++]));\n";
}
+
void writePCHReadArgs(raw_ostream &OS) const override {
OS << getLowerName();
}
+
void writePCHWrite(raw_ostream &OS) const override {
OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
}
+
void writeValue(raw_ostream &OS) const override {
// FIXME: this isn't 100% correct -- some enum arguments require printing
// as a string literal, while others require printing as an identifier.
@@ -696,6 +802,7 @@ namespace {
OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << type << "ToStr(get"
<< getUpperName() << "()) << \"\\\"";
}
+
void writeDump(raw_ostream &OS) const override {
OS << " switch(SA->get" << getUpperName() << "()) {\n";
for (const auto &I : uniques) {
@@ -784,6 +891,7 @@ namespace {
VariadicArgument::writeDeclarations(OS);
}
+
void writeDump(raw_ostream &OS) const override {
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
@@ -797,6 +905,7 @@ namespace {
OS << " }\n";
OS << " }\n";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
OS << " SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName()
@@ -807,6 +916,7 @@ namespace {
OS << " " << getLowerName() << ".push_back(" << "static_cast<"
<< QualifiedTypeName << ">(Record[Idx++]));\n";
}
+
void writePCHWrite(raw_ostream &OS) const override {
OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
@@ -814,6 +924,7 @@ namespace {
<< getLowerName() << "_end(); i != e; ++i)\n";
OS << " " << WritePCHRecord(QualifiedTypeName, "(*i)");
}
+
void writeConversion(raw_ostream &OS) const {
OS << " static bool ConvertStrTo" << type << "(StringRef Val, ";
OS << type << " &Out) {\n";
@@ -859,37 +970,48 @@ namespace {
OS << " " << getLowerName() << " = V;\n";
OS << " }";
}
+
void writeCloneArgs(raw_ostream &OS) const override {
OS << "get" << getUpperName() << "()";
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
OS << "A->get" << getUpperName() << "()";
}
+
void writeCtorInitializers(raw_ostream &OS) const override {
OS << getLowerName() << "(" << getUpperName() << ")";
}
+
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
OS << getLowerName() << "()";
}
+
void writeCtorParameters(raw_ostream &OS) const override {
OS << "VersionTuple " << getUpperName();
}
+
void writeDeclarations(raw_ostream &OS) const override {
OS << "VersionTuple " << getLowerName() << ";\n";
}
+
void writePCHReadDecls(raw_ostream &OS) const override {
OS << " VersionTuple " << getLowerName()
<< "= ReadVersionTuple(Record, Idx);\n";
}
+
void writePCHReadArgs(raw_ostream &OS) const override {
OS << getLowerName();
}
+
void writePCHWrite(raw_ostream &OS) const override {
- OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
+ OS << " Record.AddVersionTuple(SA->get" << getUpperName() << "());\n";
}
+
void writeValue(raw_ostream &OS) const override {
OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
}
+
void writeDump(raw_ostream &OS) const override {
OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
}
@@ -928,6 +1050,7 @@ namespace {
void writeDumpChildren(raw_ostream &OS) const override {
OS << " dumpStmt(SA->get" << getUpperName() << "());\n";
}
+
void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
};
@@ -993,8 +1116,21 @@ namespace {
class VariadicStringArgument : public VariadicArgument {
public:
VariadicStringArgument(const Record &Arg, StringRef Attr)
- : VariadicArgument(Arg, Attr, "std::string")
+ : VariadicArgument(Arg, Attr, "StringRef")
{}
+
+ void writeCtorBody(raw_ostream &OS) const override {
+ OS << " for (size_t I = 0, E = " << getArgSizeName() << "; I != E;\n"
+ " ++I) {\n"
+ " StringRef Ref = " << getUpperName() << "[I];\n"
+ " if (!Ref.empty()) {\n"
+ " char *Mem = new (Ctx, 1) char[Ref.size()];\n"
+ " std::memcpy(Mem, Ref.data(), Ref.size());\n"
+ " " << getArgName() << "[I] = StringRef(Mem, Ref.size());\n"
+ " }\n"
+ " }\n";
+ }
+
void writeValueImpl(raw_ostream &OS) const override {
OS << " OS << \"\\\"\" << Val << \"\\\"\";\n";
}
@@ -1014,14 +1150,17 @@ namespace {
OS << " return " << getLowerName() << ";\n";
OS << " }";
}
+
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
OS << "A->get" << getUpperName() << "Loc()";
}
+
void writePCHWrite(raw_ostream &OS) const override {
OS << " " << WritePCHRecord(
getType(), "SA->get" + std::string(getUpperName()) + "Loc()");
}
};
+
} // end anonymous namespace
static std::unique_ptr<Argument>
@@ -1072,9 +1211,9 @@ createArgument(const Record &Arg, StringRef Attr,
if (!Ptr) {
// Search in reverse order so that the most-derived type is handled first.
- ArrayRef<Record*> Bases = Search->getSuperClasses();
- for (const auto *Base : llvm::make_range(Bases.rbegin(), Bases.rend())) {
- if ((Ptr = createArgument(Arg, Attr, Base)))
+ ArrayRef<std::pair<Record*, SMRange>> Bases = Search->getSuperClasses();
+ for (const auto &Base : llvm::reverse(Bases)) {
+ if ((Ptr = createArgument(Arg, Attr, Base.first)))
break;
}
}
@@ -1090,6 +1229,7 @@ createArgument(const Record &Arg, StringRef Attr,
static void writeAvailabilityValue(raw_ostream &OS) {
OS << "\" << getPlatform()->getName();\n"
+ << " if (getStrict()) OS << \", strict\";\n"
<< " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
<< " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
<< " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
@@ -1097,6 +1237,15 @@ static void writeAvailabilityValue(raw_ostream &OS) {
<< " OS << \"";
}
+static void writeDeprecatedAttrValue(raw_ostream &OS, std::string &Variety) {
+ OS << "\\\"\" << getMessage() << \"\\\"\";\n";
+ // Only GNU deprecated has an optional fixit argument at the second position.
+ if (Variety == "GNU")
+ OS << " if (!getReplacement().empty()) OS << \", \\\"\""
+ " << getReplacement() << \"\\\"\";\n";
+ OS << " OS << \"";
+}
+
static void writeGetSpellingFunction(Record &R, raw_ostream &OS) {
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
@@ -1210,6 +1359,8 @@ writePrettyPrintFunction(Record &R,
OS << "(";
if (Spelling == "availability") {
writeAvailabilityValue(OS);
+ } else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") {
+ writeDeprecatedAttrValue(OS, Variety);
} else {
unsigned index = 0;
for (const auto &arg : Args) {
@@ -1303,10 +1454,10 @@ CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings,
unsigned Idx = 0;
for (auto I = Spellings.begin(), E = Spellings.end(); I != E; ++I, ++Idx) {
const FlattenedSpelling &S = *I;
- std::string Variety = S.variety();
- std::string Spelling = S.name();
- std::string Namespace = S.nameSpace();
- std::string EnumName = "";
+ const std::string &Variety = S.variety();
+ const std::string &Spelling = S.name();
+ const std::string &Namespace = S.nameSpace();
+ std::string EnumName;
EnumName += (Variety + "_");
if (!Namespace.empty())
@@ -1381,7 +1532,7 @@ static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
if (Args.empty())
continue;
- if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
+ if (Args[0]->getSuperClasses().back().first->getName() != "TypeArgument")
continue;
// All these spellings take a single type argument.
@@ -1419,7 +1570,7 @@ static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS)
static bool isIdentifierArgument(Record *Arg) {
return !Arg->getSuperClasses().empty() &&
- llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
+ llvm::StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
.Case("IdentifierArgument", true)
.Case("EnumArgument", true)
.Case("VariadicEnumArgument", true)
@@ -1476,13 +1627,13 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
if (!R.getValueAsBit("ASTNode"))
continue;
- ArrayRef<Record *> Supers = R.getSuperClasses();
+ ArrayRef<std::pair<Record *, SMRange>> Supers = R.getSuperClasses();
assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
std::string SuperName;
- for (const auto *Super : llvm::make_range(Supers.rbegin(), Supers.rend())) {
- const Record &R = *Super;
- if (R.getName() != "TargetSpecificAttr" && SuperName.empty())
- SuperName = R.getName();
+ for (const auto &Super : llvm::reverse(Supers)) {
+ const Record *R = Super.first;
+ if (R->getName() != "TargetSpecificAttr" && SuperName.empty())
+ SuperName = R->getName();
}
OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
@@ -1506,7 +1657,7 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
}
}
- OS << "\npublic:\n";
+ OS << "public:\n";
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
@@ -1576,8 +1727,8 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
OS << " )\n";
OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI, "
- << R.getValueAsBit("LateParsed") << ", "
- << R.getValueAsBit("DuplicatesAllowedWhileMerging") << ")\n";
+ << ( R.getValueAsBit("LateParsed") ? "true" : "false" ) << ", "
+ << ( R.getValueAsBit("DuplicatesAllowedWhileMerging") ? "true" : "false" ) << ")\n";
for (auto const &ai : Args) {
OS << " , ";
@@ -1594,10 +1745,8 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
for (auto const &ai : Args) {
if (!shouldEmitArg(ai)) continue;
ai->writeCtorBody(OS);
- OS << "\n";
}
OS << " }\n\n";
-
};
// Emit a constructor that includes all the arguments.
@@ -1705,8 +1854,6 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
OS << " return cast<" << R.getName() << "Attr>(this)->" << Method
<< ";\n";
}
- OS << " case attr::NUM_ATTRS:\n";
- OS << " break;\n";
OS << " }\n";
OS << " llvm_unreachable(\"Unexpected attribute kind!\");\n";
OS << "}\n\n";
@@ -1725,20 +1872,10 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
} // end namespace clang
-static void EmitAttrList(raw_ostream &OS, StringRef Class,
+static void emitAttrList(raw_ostream &OS, StringRef Class,
const std::vector<Record*> &AttrList) {
- auto i = AttrList.cbegin(), e = AttrList.cend();
-
- if (i != e) {
- // Move the end iterator back to emit the last attribute.
- for(--e; i != e; ++i) {
- if (!(*i)->getValueAsBit("ASTNode"))
- continue;
-
- OS << Class << "(" << (*i)->getName() << ")\n";
- }
-
- OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
+ for (auto Cur : AttrList) {
+ OS << Class << "(" << Cur->getName() << ")\n";
}
}
@@ -1751,71 +1888,224 @@ static bool AttrHasPragmaSpelling(const Record *R) {
}) != Spellings.end();
}
-namespace clang {
-// Emits the enumeration list for attributes.
-void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
- emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
+namespace {
- OS << "#ifndef LAST_ATTR\n";
- OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
- OS << "#endif\n\n";
+ struct AttrClassDescriptor {
+ const char * const MacroName;
+ const char * const TableGenName;
+ };
- OS << "#ifndef INHERITABLE_ATTR\n";
- OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
- OS << "#endif\n\n";
+} // end anonymous namespace
- OS << "#ifndef LAST_INHERITABLE_ATTR\n";
- OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
- OS << "#endif\n\n";
+static const AttrClassDescriptor AttrClassDescriptors[] = {
+ { "ATTR", "Attr" },
+ { "STMT_ATTR", "StmtAttr" },
+ { "INHERITABLE_ATTR", "InheritableAttr" },
+ { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
+ { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
+};
- OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
- OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
- OS << "#endif\n\n";
+static void emitDefaultDefine(raw_ostream &OS, StringRef name,
+ const char *superName) {
+ OS << "#ifndef " << name << "\n";
+ OS << "#define " << name << "(NAME) ";
+ if (superName) OS << superName << "(NAME)";
+ OS << "\n#endif\n\n";
+}
- OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
- OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
- " INHERITABLE_PARAM_ATTR(NAME)\n";
- OS << "#endif\n\n";
+namespace {
- OS << "#ifndef PRAGMA_SPELLING_ATTR\n";
- OS << "#define PRAGMA_SPELLING_ATTR(NAME)\n";
- OS << "#endif\n\n";
+ /// A class of attributes.
+ struct AttrClass {
+ const AttrClassDescriptor &Descriptor;
+ Record *TheRecord;
+ AttrClass *SuperClass = nullptr;
+ std::vector<AttrClass*> SubClasses;
+ std::vector<Record*> Attrs;
+
+ AttrClass(const AttrClassDescriptor &Descriptor, Record *R)
+ : Descriptor(Descriptor), TheRecord(R) {}
+
+ void emitDefaultDefines(raw_ostream &OS) const {
+ // Default the macro unless this is a root class (i.e. Attr).
+ if (SuperClass) {
+ emitDefaultDefine(OS, Descriptor.MacroName,
+ SuperClass->Descriptor.MacroName);
+ }
+ }
- OS << "#ifndef LAST_PRAGMA_SPELLING_ATTR\n";
- OS << "#define LAST_PRAGMA_SPELLING_ATTR(NAME) PRAGMA_SPELLING_ATTR(NAME)\n";
- OS << "#endif\n\n";
+ void emitUndefs(raw_ostream &OS) const {
+ OS << "#undef " << Descriptor.MacroName << "\n";
+ }
- Record *InhClass = Records.getClass("InheritableAttr");
- Record *InhParamClass = Records.getClass("InheritableParamAttr");
- std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"),
- NonInhAttrs, InhAttrs, InhParamAttrs, PragmaAttrs;
+ void emitAttrList(raw_ostream &OS) const {
+ for (auto SubClass : SubClasses) {
+ SubClass->emitAttrList(OS);
+ }
+
+ ::emitAttrList(OS, Descriptor.MacroName, Attrs);
+ }
+
+ void classifyAttrOnRoot(Record *Attr) {
+ bool result = classifyAttr(Attr);
+ assert(result && "failed to classify on root"); (void) result;
+ }
+
+ void emitAttrRange(raw_ostream &OS) const {
+ OS << "ATTR_RANGE(" << Descriptor.TableGenName
+ << ", " << getFirstAttr()->getName()
+ << ", " << getLastAttr()->getName() << ")\n";
+ }
+
+ private:
+ bool classifyAttr(Record *Attr) {
+ // Check all the subclasses.
+ for (auto SubClass : SubClasses) {
+ if (SubClass->classifyAttr(Attr))
+ return true;
+ }
+
+ // It's not more specific than this class, but it might still belong here.
+ if (Attr->isSubClassOf(TheRecord)) {
+ Attrs.push_back(Attr);
+ return true;
+ }
+
+ return false;
+ }
+
+ Record *getFirstAttr() const {
+ if (!SubClasses.empty())
+ return SubClasses.front()->getFirstAttr();
+ return Attrs.front();
+ }
+
+ Record *getLastAttr() const {
+ if (!Attrs.empty())
+ return Attrs.back();
+ return SubClasses.back()->getLastAttr();
+ }
+ };
+
+ /// The entire hierarchy of attribute classes.
+ class AttrClassHierarchy {
+ std::vector<std::unique_ptr<AttrClass>> Classes;
+
+ public:
+ AttrClassHierarchy(RecordKeeper &Records) {
+ // Find records for all the classes.
+ for (auto &Descriptor : AttrClassDescriptors) {
+ Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
+ AttrClass *Class = new AttrClass(Descriptor, ClassRecord);
+ Classes.emplace_back(Class);
+ }
+
+ // Link up the hierarchy.
+ for (auto &Class : Classes) {
+ if (AttrClass *SuperClass = findSuperClass(Class->TheRecord)) {
+ Class->SuperClass = SuperClass;
+ SuperClass->SubClasses.push_back(Class.get());
+ }
+ }
+
+#ifndef NDEBUG
+ for (auto i = Classes.begin(), e = Classes.end(); i != e; ++i) {
+ assert((i == Classes.begin()) == ((*i)->SuperClass == nullptr) &&
+ "only the first class should be a root class!");
+ }
+#endif
+ }
+
+ void emitDefaultDefines(raw_ostream &OS) const {
+ for (auto &Class : Classes) {
+ Class->emitDefaultDefines(OS);
+ }
+ }
+
+ void emitUndefs(raw_ostream &OS) const {
+ for (auto &Class : Classes) {
+ Class->emitUndefs(OS);
+ }
+ }
+
+ void emitAttrLists(raw_ostream &OS) const {
+ // Just start from the root class.
+ Classes[0]->emitAttrList(OS);
+ }
+
+ void emitAttrRanges(raw_ostream &OS) const {
+ for (auto &Class : Classes)
+ Class->emitAttrRange(OS);
+ }
+
+ void classifyAttr(Record *Attr) {
+ // Add the attribute to the root class.
+ Classes[0]->classifyAttrOnRoot(Attr);
+ }
+
+ private:
+ AttrClass *findClassByRecord(Record *R) const {
+ for (auto &Class : Classes) {
+ if (Class->TheRecord == R)
+ return Class.get();
+ }
+ return nullptr;
+ }
+
+ AttrClass *findSuperClass(Record *R) const {
+ // TableGen flattens the superclass list, so we just need to walk it
+ // in reverse.
+ auto SuperClasses = R->getSuperClasses();
+ for (signed i = 0, e = SuperClasses.size(); i != e; ++i) {
+ auto SuperClass = findClassByRecord(SuperClasses[e - i - 1].first);
+ if (SuperClass) return SuperClass;
+ }
+ return nullptr;
+ }
+ };
+
+} // end anonymous namespace
+
+namespace clang {
+
+// Emits the enumeration list for attributes.
+void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
+ emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
+
+ AttrClassHierarchy Hierarchy(Records);
+
+ // Add defaulting macro definitions.
+ Hierarchy.emitDefaultDefines(OS);
+ emitDefaultDefine(OS, "PRAGMA_SPELLING_ATTR", nullptr);
+
+ std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+ std::vector<Record *> PragmaAttrs;
for (auto *Attr : Attrs) {
if (!Attr->getValueAsBit("ASTNode"))
continue;
+ // Add the attribute to the ad-hoc groups.
if (AttrHasPragmaSpelling(Attr))
PragmaAttrs.push_back(Attr);
- if (Attr->isSubClassOf(InhParamClass))
- InhParamAttrs.push_back(Attr);
- else if (Attr->isSubClassOf(InhClass))
- InhAttrs.push_back(Attr);
- else
- NonInhAttrs.push_back(Attr);
+ // Place it in the hierarchy.
+ Hierarchy.classifyAttr(Attr);
}
- EmitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs);
- EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
- EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
- EmitAttrList(OS, "ATTR", NonInhAttrs);
+ // Emit the main attribute list.
+ Hierarchy.emitAttrLists(OS);
+
+ // Emit the ad hoc groups.
+ emitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs);
- OS << "#undef LAST_ATTR\n";
- OS << "#undef INHERITABLE_ATTR\n";
- OS << "#undef LAST_INHERITABLE_ATTR\n";
- OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
- OS << "#undef LAST_PRAGMA_ATTR\n";
+ // Emit the attribute ranges.
+ OS << "#ifdef ATTR_RANGE\n";
+ Hierarchy.emitAttrRanges(OS);
+ OS << "#undef ATTR_RANGE\n";
+ OS << "#endif\n";
+
+ Hierarchy.emitUndefs(OS);
OS << "#undef PRAGMA_SPELLING_ATTR\n";
- OS << "#undef ATTR\n";
}
// Emits the code to read an attribute from a precompiled header.
@@ -1828,8 +2118,6 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
std::vector<std::unique_ptr<Argument>> Args;
OS << " switch (Kind) {\n";
- OS << " default:\n";
- OS << " llvm_unreachable(\"Unknown attribute!\");\n";
for (const auto *Attr : Attrs) {
const Record &R = *Attr;
if (!R.getValueAsBit("ASTNode"))
@@ -1869,9 +2157,6 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
OS << " switch (A->getKind()) {\n";
- OS << " default:\n";
- OS << " llvm_unreachable(\"Unknown attribute kind!\");\n";
- OS << " break;\n";
for (const auto *Attr : Attrs) {
const Record &R = *Attr;
if (!R.getValueAsBit("ASTNode"))
@@ -2018,7 +2303,7 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
for (auto *R : Attrs) {
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
for (const auto &SI : Spellings) {
- std::string Variety = SI.variety();
+ const std::string &Variety = SI.variety();
if (Variety == "GNU")
GNU.push_back(R);
else if (Variety == "Declspec")
@@ -2062,11 +2347,7 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Code to translate different attribute spellings "
"into internal identifiers", OS);
- OS <<
- " switch (AttrKind) {\n"
- " default:\n"
- " llvm_unreachable(\"Unknown attribute kind!\");\n"
- " break;\n";
+ OS << " switch (AttrKind) {\n";
ParsedAttrMap Attrs = getParsedAttrList(Records);
for (const auto &I : Attrs) {
@@ -2146,9 +2427,7 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
<< " if (!A)\n"
<< " return true;\n"
<< "\n"
- << " switch (A->getKind()) {\n"
- << " default:\n"
- << " return true;\n";
+ << " switch (A->getKind()) {\n";
for (const auto *Attr : Attrs) {
const Record &R = *Attr;
@@ -2159,7 +2438,8 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
<< " return getDerived().Traverse" << R.getName() << "Attr("
<< "cast<" << R.getName() << "Attr>(A));\n";
}
- OS << " }\n"; // end case
+ OS << " }\n"; // end switch
+ OS << " llvm_unreachable(\"bad attribute kind\");\n";
OS << "}\n"; // end function
OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n";
}
@@ -2175,9 +2455,7 @@ void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
<< "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
<< "Sema &S,\n"
<< " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
- << " switch (At->getKind()) {\n"
- << " default:\n"
- << " break;\n";
+ << " switch (At->getKind()) {\n";
for (const auto *Attr : Attrs) {
const Record &R = *Attr;
@@ -2375,6 +2653,15 @@ static std::string CalculateDiagnostic(const Record &S) {
return "(S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : "
"ExpectedVariableOrFunction)";
+ case Func | Var | Class | ObjCInterface:
+ return "(S.getLangOpts().CPlusPlus"
+ " ? ((S.getLangOpts().ObjC1 || S.getLangOpts().ObjC2)"
+ " ? ExpectedFunctionVariableClassOrObjCInterface"
+ " : ExpectedFunctionVariableOrClass)"
+ " : ((S.getLangOpts().ObjC1 || S.getLangOpts().ObjC2)"
+ " ? ExpectedFunctionVariableOrObjCInterface"
+ " : ExpectedVariableOrFunction))";
+
case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
case ObjCProtocol | ObjCInterface:
return "ExpectedObjectiveCInterfaceOrProtocol";
@@ -2671,6 +2958,7 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
SS << ", " << I->second->getValueAsBit("HasCustomParsing");
SS << ", " << I->second->isSubClassOf("TargetSpecificAttr");
SS << ", " << I->second->isSubClassOf("TypeAttr");
+ SS << ", " << I->second->isSubClassOf("StmtAttr");
SS << ", " << IsKnownToGCC(*I->second);
SS << ", " << GenerateAppertainsTo(*I->second, OS);
SS << ", " << GenerateLangOptRequirements(*I->second, OS);
@@ -2724,9 +3012,10 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
for (const auto &S : Spellings) {
- std::string RawSpelling = S.name();
+ const std::string &RawSpelling = S.name();
std::vector<StringMatcher::StringPair> *Matches = nullptr;
- std::string Spelling, Variety = S.variety();
+ std::string Spelling;
+ const std::string &Variety = S.variety();
if (Variety == "CXX11") {
Matches = &CXX11;
Spelling += S.nameSpace();
@@ -2775,11 +3064,7 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute dumper", OS);
- OS <<
- " switch (A->getKind()) {\n"
- " default:\n"
- " llvm_unreachable(\"Unknown attribute kind!\");\n"
- " break;\n";
+ OS << " switch (A->getKind()) {\n";
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
for (const auto *Attr : Attrs) {
const Record &R = *Attr;
diff --git a/gnu/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/gnu/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
index efce5219031..bbc2bdb065f 100644
--- a/gnu/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/gnu/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -152,13 +152,12 @@ static bool beforeThanCompareGroups(const GroupInfo *LHS, const GroupInfo *RHS){
}
static SMRange findSuperClassRange(const Record *R, StringRef SuperName) {
- ArrayRef<Record *> Supers = R->getSuperClasses();
-
- for (size_t i = 0, e = Supers.size(); i < e; ++i)
- if (Supers[i]->getName() == SuperName)
- return R->getSuperClassRanges()[i];
-
- return SMRange();
+ ArrayRef<std::pair<Record *, SMRange>> Supers = R->getSuperClasses();
+ auto I = std::find_if(Supers.begin(), Supers.end(),
+ [&](const std::pair<Record *, SMRange> &SuperPair) {
+ return SuperPair.first->getName() == SuperName;
+ });
+ return (I != Supers.end()) ? I->second : SMRange();
}
/// \brief Invert the 1-[0/1] mapping of diags to group into a one to many
diff --git a/gnu/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp b/gnu/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp
index 6e7bc9057fd..b5313a073d1 100644
--- a/gnu/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp
+++ b/gnu/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp
@@ -40,6 +40,7 @@
#include <map>
#include <sstream>
#include <string>
+#include <utility>
#include <vector>
using namespace llvm;
@@ -146,9 +147,10 @@ public:
NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {}
Type(TypeSpec TS, char CharMod)
- : TS(TS), Float(false), Signed(false), Immediate(false), Void(false),
- Poly(false), Constant(false), Pointer(false), ScalarForMangling(false),
- NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {
+ : TS(std::move(TS)), Float(false), Signed(false), Immediate(false),
+ Void(false), Poly(false), Constant(false), Pointer(false),
+ ScalarForMangling(false), NoManglingQ(false), Bitwidth(0),
+ ElementBitwidth(0), NumVectors(0) {
applyModifier(CharMod);
}
@@ -257,7 +259,7 @@ class Variable {
public:
Variable() : T(Type::getVoid()), N("") {}
- Variable(Type T, std::string N) : T(T), N(N) {}
+ Variable(Type T, std::string N) : T(std::move(T)), N(std::move(N)) {}
Type getType() const { return T; }
std::string getName() const { return "__" + N; }
@@ -1195,12 +1197,12 @@ void Intrinsic::emitReverseVariable(Variable &Dest, Variable &Src) {
emitNewLine();
for (unsigned K = 0; K < Dest.getType().getNumVectors(); ++K) {
- OS << " " << Dest.getName() << ".val[" << utostr(K) << "] = "
+ OS << " " << Dest.getName() << ".val[" << K << "] = "
<< "__builtin_shufflevector("
- << Src.getName() << ".val[" << utostr(K) << "], "
- << Src.getName() << ".val[" << utostr(K) << "]";
+ << Src.getName() << ".val[" << K << "], "
+ << Src.getName() << ".val[" << K << "]";
for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J)
- OS << ", " << utostr(J);
+ OS << ", " << J;
OS << ");";
emitNewLine();
}
@@ -1208,7 +1210,7 @@ void Intrinsic::emitReverseVariable(Variable &Dest, Variable &Src) {
OS << " " << Dest.getName()
<< " = __builtin_shufflevector(" << Src.getName() << ", " << Src.getName();
for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J)
- OS << ", " << utostr(J);
+ OS << ", " << J;
OS << ");";
emitNewLine();
}
@@ -1926,7 +1928,7 @@ void NeonEmitter::createIntrinsic(Record *R,
ClassKind CK = ClassNone;
if (R->getSuperClasses().size() >= 2)
- CK = ClassMap[R->getSuperClasses()[1]];
+ CK = ClassMap[R->getSuperClasses()[1].first];
std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs;
for (auto TS : TypeSpecs) {
diff --git a/gnu/llvm/tools/clang/utils/TableGen/TableGen.cpp b/gnu/llvm/tools/clang/utils/TableGen/TableGen.cpp
index 724b0e19586..7ccd7150319 100644
--- a/gnu/llvm/tools/clang/utils/TableGen/TableGen.cpp
+++ b/gnu/llvm/tools/clang/utils/TableGen/TableGen.cpp
@@ -241,7 +241,7 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
}
int main(int argc, char **argv) {
- sys::PrintStackTraceOnErrorSignal();
+ sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
diff --git a/gnu/llvm/tools/clang/utils/analyzer/SATestBuild.py b/gnu/llvm/tools/clang/utils/analyzer/SATestBuild.py
index d0503c6389c..ab68518b5ac 100755
--- a/gnu/llvm/tools/clang/utils/analyzer/SATestBuild.py
+++ b/gnu/llvm/tools/clang/utils/analyzer/SATestBuild.py
@@ -218,11 +218,11 @@ def runScript(ScriptPath, PBuildLogFile, Cwd):
try:
if Verbose == 1:
print " Executing: %s" % (ScriptPath,)
- check_call("chmod +x %s" % ScriptPath, cwd = Cwd,
+ check_call("chmod +x '%s'" % ScriptPath, cwd = Cwd,
stderr=PBuildLogFile,
stdout=PBuildLogFile,
shell=True)
- check_call(ScriptPath, cwd = Cwd, stderr=PBuildLogFile,
+ check_call("'%s'" % ScriptPath, cwd = Cwd, stderr=PBuildLogFile,
stdout=PBuildLogFile,
shell=True)
except:
@@ -261,7 +261,7 @@ def applyPatch(Dir, PBuildLogFile):
print " Applying patch."
try:
- check_call("patch -p1 < %s" % (PatchfilePath),
+ check_call("patch -p1 < '%s'" % (PatchfilePath),
cwd = PatchedSourceDirPath,
stderr=PBuildLogFile,
stdout=PBuildLogFile,
@@ -285,8 +285,8 @@ def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
# Run scan-build from within the patched source directory.
SBCwd = os.path.join(Dir, PatchedSourceDirName)
- SBOptions = "--use-analyzer " + Clang + " "
- SBOptions += "-plist-html -o " + SBOutputDir + " "
+ SBOptions = "--use-analyzer '%s' " % Clang
+ SBOptions += "-plist-html -o '%s' " % SBOutputDir
SBOptions += "-enable-checker " + AllCheckers + " "
SBOptions += "--keep-empty "
# Always use ccc-analyze to ensure that we can locate the failures
@@ -376,8 +376,8 @@ def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
raise Exception()
# Build and call the analyzer command.
- OutputOption = "-o " + os.path.join(PlistPath, FileName) + ".plist "
- Command = CmdPrefix + OutputOption + FileName
+ OutputOption = "-o '%s.plist' " % os.path.join(PlistPath, FileName)
+ Command = CmdPrefix + OutputOption + ("'%s'" % FileName)
LogFile = open(os.path.join(FailPath, FileName + ".stderr.txt"), "w+b")
try:
if Verbose == 1:
@@ -397,23 +397,30 @@ def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
if Failed == False:
os.remove(LogFile.name);
+def getBuildLogPath(SBOutputDir):
+ return os.path.join(SBOutputDir, LogFolderName, BuildLogName)
+
+def removeLogFile(SBOutputDir):
+ BuildLogPath = getBuildLogPath(SBOutputDir)
+ # Clean up the log file.
+ if (os.path.exists(BuildLogPath)) :
+ RmCommand = "rm '%s'" % BuildLogPath
+ if Verbose == 1:
+ print " Executing: %s" % (RmCommand,)
+ check_call(RmCommand, shell=True)
+
def buildProject(Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild):
TBegin = time.time()
- BuildLogPath = os.path.join(SBOutputDir, LogFolderName, BuildLogName)
+ BuildLogPath = getBuildLogPath(SBOutputDir)
print "Log file: %s" % (BuildLogPath,)
print "Output directory: %s" %(SBOutputDir, )
- # Clean up the log file.
- if (os.path.exists(BuildLogPath)) :
- RmCommand = "rm " + BuildLogPath
- if Verbose == 1:
- print " Executing: %s" % (RmCommand,)
- check_call(RmCommand, shell=True)
+ removeLogFile(SBOutputDir)
# Clean up scan build results.
if (os.path.exists(SBOutputDir)) :
- RmCommand = "rm -r " + SBOutputDir
+ RmCommand = "rm -r '%s'" % SBOutputDir
if Verbose == 1:
print " Executing: %s" % (RmCommand,)
check_call(RmCommand, shell=True)
@@ -585,6 +592,19 @@ def runCmpResults(Dir, Strictness = 0):
print "Diagnostic comparison complete (time: %.2f)." % (time.time()-TBegin)
return (NumDiffs > 0)
+def cleanupReferenceResults(SBOutputDir):
+ # Delete html, css, and js files from reference results. These can
+ # include multiple copies of the benchmark source and so get very large.
+ Extensions = ["html", "css", "js"]
+ for E in Extensions:
+ for F in glob.glob("%s/*/*.%s" % (SBOutputDir, E)):
+ P = os.path.join(SBOutputDir, F)
+ RmCommand = "rm '%s'" % P
+ check_call(RmCommand, shell=True)
+
+ # Remove the log file. It leaks absolute path names.
+ removeLogFile(SBOutputDir)
+
def updateSVN(Mode, ProjectsMap):
try:
ProjectsMap.seek(0)
@@ -593,9 +613,9 @@ def updateSVN(Mode, ProjectsMap):
Path = os.path.join(ProjName, getSBOutputDirName(True))
if Mode == "delete":
- Command = "svn delete %s" % (Path,)
+ Command = "svn delete '%s'" % (Path,)
else:
- Command = "svn add %s" % (Path,)
+ Command = "svn add '%s'" % (Path,)
if Verbose == 1:
print " Executing: %s" % (Command,)
@@ -634,6 +654,8 @@ def testProject(ID, ProjectBuildMode, IsReferenceBuild=False, Dir=None, Strictne
if IsReferenceBuild == False:
runCmpResults(Dir, Strictness)
+ else:
+ cleanupReferenceResults(SBOutputDir)
print "Completed tests for project %s (time: %.2f)." % \
(ID, (time.time()-TBegin))
diff --git a/gnu/llvm/tools/clang/utils/modfuzz.py b/gnu/llvm/tools/clang/utils/modfuzz.py
new file mode 100644
index 00000000000..a6aa1f1a257
--- /dev/null
+++ b/gnu/llvm/tools/clang/utils/modfuzz.py
@@ -0,0 +1,166 @@
+#! /usr/bin/env python
+
+# To use:
+# 1) Update the 'decls' list below with your fuzzing configuration.
+# 2) Run with the clang binary as the command-line argument.
+
+import random
+import subprocess
+import sys
+import os
+
+clang = sys.argv[1]
+none_opts = 0.3
+
+class Decl:
+ def __init__(self, text, depends=[], provides=[], conflicts=[]):
+ self.text = text
+ self.depends = depends
+ self.provides = provides
+ self.conflicts = conflicts
+
+ def valid(self, model):
+ for i in self.depends:
+ if i not in model.decls:
+ return False
+ for i in self.conflicts:
+ if i in model.decls:
+ return False
+ return True
+
+ def apply(self, model, name):
+ for i in self.provides:
+ model.decls[i] = True
+ model.source += self.text % {'name': name}
+
+decls = [
+ Decl('struct X { int n; };\n', provides=['X'], conflicts=['X']),
+ Decl('static_assert(X{.n=1}.n == 1, "");\n', depends=['X']),
+ Decl('X %(name)s;\n', depends=['X']),
+]
+
+class FS:
+ def __init__(self):
+ self.fs = {}
+ self.prevfs = {}
+
+ def write(self, path, contents):
+ self.fs[path] = contents
+
+ def done(self):
+ for f, s in self.fs.items():
+ if self.prevfs.get(f) != s:
+ f = file(f, 'w')
+ f.write(s)
+ f.close()
+
+ for f in self.prevfs:
+ if f not in self.fs:
+ os.remove(f)
+
+ self.prevfs, self.fs = self.fs, {}
+
+fs = FS()
+
+class CodeModel:
+ def __init__(self):
+ self.source = ''
+ self.modules = {}
+ self.decls = {}
+ self.i = 0
+
+ def make_name(self):
+ self.i += 1
+ return 'n' + str(self.i)
+
+ def fails(self):
+ fs.write('module.modulemap',
+ ''.join('module %s { header "%s.h" export * }\n' % (m, m)
+ for m in self.modules.keys()))
+
+ for m, (s, _) in self.modules.items():
+ fs.write('%s.h' % m, s)
+
+ fs.write('main.cc', self.source)
+ fs.done()
+
+ return subprocess.call([clang, '-std=c++11', '-c', '-fmodules', 'main.cc', '-o', '/dev/null']) != 0
+
+def generate():
+ model = CodeModel()
+ m = []
+
+ try:
+ for d in mutations(model):
+ d(model)
+ m.append(d)
+ if not model.fails():
+ return
+ except KeyboardInterrupt:
+ print
+ return True
+
+ sys.stdout.write('\nReducing:\n')
+ sys.stdout.flush()
+
+ try:
+ while True:
+ assert m, 'got a failure with no steps; broken clang binary?'
+ i = random.choice(range(len(m)))
+ x = m[0:i] + m[i+1:]
+ m2 = CodeModel()
+ for d in x:
+ d(m2)
+ if m2.fails():
+ m = x
+ model = m2
+ else:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ except KeyboardInterrupt:
+ # FIXME: Clean out output directory first.
+ model.fails()
+ return model
+
+def choose(options):
+ while True:
+ i = int(random.uniform(0, len(options) + none_opts))
+ if i >= len(options):
+ break
+ yield options[i]
+
+def mutations(model):
+ options = [create_module, add_top_level_decl]
+ for opt in choose(options):
+ yield opt(model, options)
+
+def create_module(model, options):
+ n = model.make_name()
+ def go(model):
+ model.modules[n] = (model.source, model.decls)
+ (model.source, model.decls) = ('', {})
+ options += [lambda model, options: add_import(model, options, n)]
+ return go
+
+def add_top_level_decl(model, options):
+ n = model.make_name()
+ d = random.choice([decl for decl in decls if decl.valid(model)])
+ def go(model):
+ if not d.valid(model):
+ return
+ d.apply(model, n)
+ return go
+
+def add_import(model, options, module_name):
+ def go(model):
+ if module_name in model.modules:
+ model.source += '#include "%s.h"\n' % module_name
+ model.decls.update(model.modules[module_name][1])
+ return go
+
+sys.stdout.write('Finding bug: ')
+while True:
+ if generate():
+ break
+ sys.stdout.write('.')
+ sys.stdout.flush()
diff --git a/gnu/llvm/tools/clang/utils/perf-training/CMakeLists.txt b/gnu/llvm/tools/clang/utils/perf-training/CMakeLists.txt
index ccedcf5d516..07d90246107 100644
--- a/gnu/llvm/tools/clang/utils/perf-training/CMakeLists.txt
+++ b/gnu/llvm/tools/clang/utils/perf-training/CMakeLists.txt
@@ -1,24 +1,28 @@
-if(LLVM_BUILD_INSTRUMENTED)
- if (CMAKE_CFG_INTDIR STREQUAL ".")
- set(LLVM_BUILD_MODE ".")
- else ()
- set(LLVM_BUILD_MODE "%(build_mode)s")
- endif ()
- string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+# All test suites added here should be excuded from check-all
+set(EXCLUDE_FROM_ALL On)
+
+if (CMAKE_CFG_INTDIR STREQUAL ".")
+ set(LLVM_BUILD_MODE ".")
+else ()
+ set(LLVM_BUILD_MODE "%(build_mode)s")
+endif ()
+
+string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+if(LLVM_BUILD_INSTRUMENTED)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ ${CMAKE_CURRENT_BINARY_DIR}/pgo-data/lit.site.cfg
)
add_lit_testsuite(generate-profraw "Generating clang PGO data"
- ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/pgo-data/
DEPENDS clang clear-profraw
)
add_custom_target(clear-profraw
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR}
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} profraw
COMMENT "Clearing old profraw data")
if(NOT LLVM_PROFDATA)
@@ -34,3 +38,26 @@ if(LLVM_BUILD_INSTRUMENTED)
COMMENT "Merging profdata"
DEPENDS generate-profraw)
endif()
+
+find_program(DTRACE dtrace)
+if(DTRACE)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/order-files.lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/order-files/lit.site.cfg
+ )
+
+ add_lit_testsuite(generate-dtrace-logs "Generating clang dtrace data"
+ ${CMAKE_CURRENT_BINARY_DIR}/order-files/
+ ARGS -j 1
+ DEPENDS clang clear-dtrace-logs
+ )
+
+ add_custom_target(clear-dtrace-logs
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} dtrace
+ COMMENT "Clearing old dtrace data")
+
+ add_custom_target(generate-order-file
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py gen-order-file --binary $<TARGET_FILE:clang> --output ${CLANG_ORDER_FILE} ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating order file"
+ DEPENDS generate-dtrace-logs)
+endif()
diff --git a/gnu/llvm/tools/clang/utils/perf-training/cxx/hello_world.cpp b/gnu/llvm/tools/clang/utils/perf-training/cxx/hello_world.cpp
index 66e00d00d26..fc9f6892eb7 100644
--- a/gnu/llvm/tools/clang/utils/perf-training/cxx/hello_world.cpp
+++ b/gnu/llvm/tools/clang/utils/perf-training/cxx/hello_world.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cpp -c %s
+// RUN: %clang_cpp_skip_driver -Wall -pedantic -c %s
#include <iostream>
int main(int, char**) {
diff --git a/gnu/llvm/tools/clang/utils/perf-training/lit.cfg b/gnu/llvm/tools/clang/utils/perf-training/lit.cfg
index af4b43b78b0..85d35514341 100644
--- a/gnu/llvm/tools/clang/utils/perf-training/lit.cfg
+++ b/gnu/llvm/tools/clang/utils/perf-training/lit.cfg
@@ -26,10 +26,13 @@ config.clang = lit.util.which('clang', config.clang_tools_dir).replace('\\', '/'
config.name = 'Clang Perf Training'
config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap']
+cc1_wrapper = '%s %s/perf-helper.py cc1' % (config.python_exe, config.test_source_root)
+
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
config.test_format = lit.formats.ShTest(use_lit_shell == "0")
+config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags)))
config.substitutions.append( ('%clang_cpp', ' %s --driver-mode=cpp %s ' % (config.clang, sysroot_flags)))
-config.substitutions.append( ('%clang_cc1', ' %s -cc1 %s ' % (config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags)))
config.substitutions.append( ('%clang', ' %s %s ' % (config.clang, sysroot_flags) ) )
config.substitutions.append( ('%test_root', config.test_exec_root ) )
diff --git a/gnu/llvm/tools/clang/utils/perf-training/lit.site.cfg.in b/gnu/llvm/tools/clang/utils/perf-training/lit.site.cfg.in
index 9dc380242e5..66683bcd528 100644
--- a/gnu/llvm/tools/clang/utils/perf-training/lit.site.cfg.in
+++ b/gnu/llvm/tools/clang/utils/perf-training/lit.site.cfg.in
@@ -1,11 +1,12 @@
+@LIT_SITE_CFG_IN_HEADER@
+
import sys
-## Autogenerated by LLVM/Clang configuration.
-# Do not edit!
config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@"
config.target_triple = "@TARGET_TRIPLE@"
+config.python_exe = "@PYTHON_EXECUTABLE@"
# Support substitution of the tools and libs dirs with user parameters. This is
# used when we can't determine the tool dir at configuration time.
diff --git a/gnu/llvm/tools/clang/utils/perf-training/order-files.lit.cfg b/gnu/llvm/tools/clang/utils/perf-training/order-files.lit.cfg
new file mode 100644
index 00000000000..75501f8c629
--- /dev/null
+++ b/gnu/llvm/tools/clang/utils/perf-training/order-files.lit.cfg
@@ -0,0 +1,41 @@
+# -*- Python -*-
+
+from lit import Test
+import lit.formats
+import lit.util
+import os
+
+def getSysrootFlagsOnDarwin(config, lit_config):
+ # On Darwin, support relocatable SDKs by providing Clang with a
+ # default system root path.
+ if 'darwin' in config.target_triple:
+ try:
+ out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
+ res = 0
+ except OSError:
+ res = -1
+ if res == 0 and out:
+ sdk_path = out
+ lit_config.note('using SDKROOT: %r' % sdk_path)
+ return '-isysroot %s' % sdk_path
+ return ''
+
+sysroot_flags = getSysrootFlagsOnDarwin(config, lit_config)
+
+config.clang = os.path.realpath(lit.util.which('clang', config.clang_tools_dir)).replace('\\', '/')
+
+config.name = 'Clang Perf Training'
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap']
+
+dtrace_wrapper = '%s %s/perf-helper.py dtrace' % (config.python_exe, config.test_source_root)
+dtrace_wrapper_cc1 = '%s %s/perf-helper.py dtrace --cc1' % (config.python_exe, config.test_source_root)
+
+use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
+config.test_format = lit.formats.ShTest(use_lit_shell == "0")
+config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s --driver-mode=cpp %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang_cpp', ' %s %s --driver-mode=cpp %s ' % (dtrace_wrapper, config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (dtrace_wrapper_cc1, config.clang, sysroot_flags)))
+config.substitutions.append( ('%clang', ' %s %s %s ' % (dtrace_wrapper, config.clang, sysroot_flags) ) )
+config.substitutions.append( ('%test_root', config.test_exec_root ) )
+
+
diff --git a/gnu/llvm/tools/clang/utils/perf-training/order-files.lit.site.cfg.in b/gnu/llvm/tools/clang/utils/perf-training/order-files.lit.site.cfg.in
new file mode 100644
index 00000000000..0490a217ad0
--- /dev/null
+++ b/gnu/llvm/tools/clang/utils/perf-training/order-files.lit.site.cfg.in
@@ -0,0 +1,21 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+import sys
+
+config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
+config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
+config.test_source_root = "@CMAKE_CURRENT_SOURCE_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.python_exe = "@PYTHON_EXECUTABLE@"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+ config.clang_tools_dir = config.clang_tools_dir % lit_config.params
+except KeyError:
+ e = sys.exc_info()[1]
+ key, = e.args
+ lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@CLANG_SOURCE_DIR@/utils/perf-training/order-files.lit.cfg")
diff --git a/gnu/llvm/tools/clang/utils/perf-training/perf-helper.py b/gnu/llvm/tools/clang/utils/perf-training/perf-helper.py
index 448801133e0..c7c4bddf895 100644
--- a/gnu/llvm/tools/clang/utils/perf-training/perf-helper.py
+++ b/gnu/llvm/tools/clang/utils/perf-training/perf-helper.py
@@ -7,36 +7,397 @@
#
#===------------------------------------------------------------------------===#
+from __future__ import print_function
+
import sys
import os
import subprocess
+import argparse
+import time
+import bisect
+import shlex
+import tempfile
+
+test_env = { 'PATH' : os.environ['PATH'] }
-def findProfrawFiles(path):
- profraw_files = []
+def findFilesWithExtension(path, extension):
+ filenames = []
for root, dirs, files in os.walk(path):
for filename in files:
- if filename.endswith(".profraw"):
- profraw_files.append(os.path.join(root, filename))
- return profraw_files
+ if filename.endswith(extension):
+ filenames.append(os.path.join(root, filename))
+ return filenames
def clean(args):
- if len(args) != 1:
- print 'Usage: %s clean <path>\n\tRemoves all *.profraw files from <path>.' % __file__
+ if len(args) != 2:
+ print('Usage: %s clean <path> <extension>\n' % __file__ +
+ '\tRemoves all files with extension from <path>.')
return 1
- for profraw in findProfrawFiles(args[0]):
- os.remove(profraw)
+ for filename in findFilesWithExtension(args[0], args[1]):
+ os.remove(filename)
return 0
def merge(args):
if len(args) != 3:
- print 'Usage: %s clean <llvm-profdata> <output> <path>\n\tMerges all profraw files from path into output.' % __file__
+ print('Usage: %s clean <llvm-profdata> <output> <path>\n' % __file__ +
+ '\tMerges all profraw files from path into output.')
return 1
cmd = [args[0], 'merge', '-o', args[1]]
- cmd.extend(findProfrawFiles(args[2]))
+ cmd.extend(findFilesWithExtension(args[2], "profraw"))
subprocess.check_call(cmd)
return 0
-commands = {'clean' : clean, 'merge' : merge}
+def dtrace(args):
+ parser = argparse.ArgumentParser(prog='perf-helper dtrace',
+ description='dtrace wrapper for order file generation')
+ parser.add_argument('--buffer-size', metavar='size', type=int, required=False,
+ default=1, help='dtrace buffer size in MB (default 1)')
+ parser.add_argument('--use-oneshot', required=False, action='store_true',
+ help='Use dtrace\'s oneshot probes')
+ parser.add_argument('--use-ustack', required=False, action='store_true',
+ help='Use dtrace\'s ustack to print function names')
+ parser.add_argument('--cc1', required=False, action='store_true',
+ help='Execute cc1 directly (don\'t profile the driver)')
+ parser.add_argument('cmd', nargs='*', help='')
+
+ # Use python's arg parser to handle all leading option arguments, but pass
+ # everything else through to dtrace
+ first_cmd = next(arg for arg in args if not arg.startswith("--"))
+ last_arg_idx = args.index(first_cmd)
+
+ opts = parser.parse_args(args[:last_arg_idx])
+ cmd = args[last_arg_idx:]
+
+ if opts.cc1:
+ cmd = get_cc1_command_for_args(cmd, test_env)
+
+ if opts.use_oneshot:
+ target = "oneshot$target:::entry"
+ else:
+ target = "pid$target:::entry"
+ predicate = '%s/probemod=="%s"/' % (target, os.path.basename(args[0]))
+ log_timestamp = 'printf("dtrace-TS: %d\\n", timestamp)'
+ if opts.use_ustack:
+ action = 'ustack(1);'
+ else:
+ action = 'printf("dtrace-Symbol: %s\\n", probefunc);'
+ dtrace_script = "%s { %s; %s }" % (predicate, log_timestamp, action)
+
+ dtrace_args = []
+ if not os.geteuid() == 0:
+ print(
+ 'Script must be run as root, or you must add the following to your sudoers:'
+ + '%%admin ALL=(ALL) NOPASSWD: /usr/sbin/dtrace')
+ dtrace_args.append("sudo")
+
+ dtrace_args.extend((
+ 'dtrace', '-xevaltime=exec',
+ '-xbufsize=%dm' % (opts.buffer_size),
+ '-q', '-n', dtrace_script,
+ '-c', ' '.join(cmd)))
+
+ if sys.platform == "darwin":
+ dtrace_args.append('-xmangled')
+
+ start_time = time.time()
+
+ with open("%d.dtrace" % os.getpid(), "w") as f:
+ subprocess.check_call(dtrace_args, stdout=f, stderr=subprocess.PIPE)
+
+ elapsed = time.time() - start_time
+ print("... data collection took %.4fs" % elapsed)
+
+ return 0
+
+def get_cc1_command_for_args(cmd, env):
+ # Find the cc1 command used by the compiler. To do this we execute the
+ # compiler with '-###' to figure out what it wants to do.
+ cmd = cmd + ['-###']
+ cc_output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env).strip()
+ cc_commands = []
+ for ln in cc_output.split('\n'):
+ # Filter out known garbage.
+ if (ln == 'Using built-in specs.' or
+ ln.startswith('Configured with:') or
+ ln.startswith('Target:') or
+ ln.startswith('Thread model:') or
+ ln.startswith('InstalledDir:') or
+ ln.startswith('LLVM Profile Note') or
+ ' version ' in ln):
+ continue
+ cc_commands.append(ln)
+
+ if len(cc_commands) != 1:
+ print('Fatal error: unable to determine cc1 command: %r' % cc_output)
+ exit(1)
+
+ cc1_cmd = shlex.split(cc_commands[0])
+ if not cc1_cmd:
+ print('Fatal error: unable to determine cc1 command: %r' % cc_output)
+ exit(1)
+
+ return cc1_cmd
+
+def cc1(args):
+ parser = argparse.ArgumentParser(prog='perf-helper cc1',
+ description='cc1 wrapper for order file generation')
+ parser.add_argument('cmd', nargs='*', help='')
+
+ # Use python's arg parser to handle all leading option arguments, but pass
+ # everything else through to dtrace
+ first_cmd = next(arg for arg in args if not arg.startswith("--"))
+ last_arg_idx = args.index(first_cmd)
+
+ opts = parser.parse_args(args[:last_arg_idx])
+ cmd = args[last_arg_idx:]
+
+ # clear the profile file env, so that we don't generate profdata
+ # when capturing the cc1 command
+ cc1_env = test_env
+ cc1_env["LLVM_PROFILE_FILE"] = os.devnull
+ cc1_cmd = get_cc1_command_for_args(cmd, cc1_env)
+
+ subprocess.check_call(cc1_cmd)
+ return 0
+
+def parse_dtrace_symbol_file(path, all_symbols, all_symbols_set,
+ missing_symbols, opts):
+ def fix_mangling(symbol):
+ if sys.platform == "darwin":
+ if symbol[0] != '_' and symbol != 'start':
+ symbol = '_' + symbol
+ return symbol
+
+ def get_symbols_with_prefix(symbol):
+ start_index = bisect.bisect_left(all_symbols, symbol)
+ for s in all_symbols[start_index:]:
+ if not s.startswith(symbol):
+ break
+ yield s
+
+ # Extract the list of symbols from the given file, which is assumed to be
+ # the output of a dtrace run logging either probefunc or ustack(1) and
+ # nothing else. The dtrace -xdemangle option needs to be used.
+ #
+ # This is particular to OS X at the moment, because of the '_' handling.
+ with open(path) as f:
+ current_timestamp = None
+ for ln in f:
+ # Drop leading and trailing whitespace.
+ ln = ln.strip()
+ if not ln.startswith("dtrace-"):
+ continue
+
+ # If this is a timestamp specifier, extract it.
+ if ln.startswith("dtrace-TS: "):
+ _,data = ln.split(': ', 1)
+ if not data.isdigit():
+ print("warning: unrecognized timestamp line %r, ignoring" % ln,
+ file=sys.stderr)
+ continue
+ current_timestamp = int(data)
+ continue
+ elif ln.startswith("dtrace-Symbol: "):
+
+ _,ln = ln.split(': ', 1)
+ if not ln:
+ continue
+
+ # If there is a '`' in the line, assume it is a ustack(1) entry in
+ # the form of <modulename>`<modulefunc>, where <modulefunc> is never
+ # truncated (but does need the mangling patched).
+ if '`' in ln:
+ yield (current_timestamp, fix_mangling(ln.split('`',1)[1]))
+ continue
+
+ # Otherwise, assume this is a probefunc printout. DTrace on OS X
+ # seems to have a bug where it prints the mangled version of symbols
+ # which aren't C++ mangled. We just add a '_' to anything but start
+ # which doesn't already have a '_'.
+ symbol = fix_mangling(ln)
+
+ # If we don't know all the symbols, or the symbol is one of them,
+ # just return it.
+ if not all_symbols_set or symbol in all_symbols_set:
+ yield (current_timestamp, symbol)
+ continue
+
+ # Otherwise, we have a symbol name which isn't present in the
+ # binary. We assume it is truncated, and try to extend it.
+
+ # Get all the symbols with this prefix.
+ possible_symbols = list(get_symbols_with_prefix(symbol))
+ if not possible_symbols:
+ continue
+
+ # If we found too many possible symbols, ignore this as a prefix.
+ if len(possible_symbols) > 100:
+ print( "warning: ignoring symbol %r " % symbol +
+ "(no match and too many possible suffixes)", file=sys.stderr)
+ continue
+
+ # Report that we resolved a missing symbol.
+ if opts.show_missing_symbols and symbol not in missing_symbols:
+ print("warning: resolved missing symbol %r" % symbol, file=sys.stderr)
+ missing_symbols.add(symbol)
+
+ # Otherwise, treat all the possible matches as having occurred. This
+ # is an over-approximation, but it should be ok in practice.
+ for s in possible_symbols:
+ yield (current_timestamp, s)
+
+def uniq(list):
+ seen = set()
+ for item in list:
+ if item not in seen:
+ yield item
+ seen.add(item)
+
+def form_by_call_order(symbol_lists):
+ # Simply strategy, just return symbols in order of occurrence, even across
+ # multiple runs.
+ return uniq(s for symbols in symbol_lists for s in symbols)
+
+def form_by_call_order_fair(symbol_lists):
+ # More complicated strategy that tries to respect the call order across all
+ # of the test cases, instead of giving a huge preference to the first test
+ # case.
+
+ # First, uniq all the lists.
+ uniq_lists = [list(uniq(symbols)) for symbols in symbol_lists]
+
+ # Compute the successors for each list.
+ succs = {}
+ for symbols in uniq_lists:
+ for a,b in zip(symbols[:-1], symbols[1:]):
+ succs[a] = items = succs.get(a, [])
+ if b not in items:
+ items.append(b)
+
+ # Emit all the symbols, but make sure to always emit all successors from any
+ # call list whenever we see a symbol.
+ #
+ # There isn't much science here, but this sometimes works better than the
+ # more naive strategy. Then again, sometimes it doesn't so more research is
+ # probably needed.
+ return uniq(s
+ for symbols in symbol_lists
+ for node in symbols
+ for s in ([node] + succs.get(node,[])))
+
+def form_by_frequency(symbol_lists):
+ # Form the order file by just putting the most commonly occurring symbols
+ # first. This assumes the data files didn't use the oneshot dtrace method.
+
+ counts = {}
+ for symbols in symbol_lists:
+ for a in symbols:
+ counts[a] = counts.get(a,0) + 1
+
+ by_count = counts.items()
+ by_count.sort(key = lambda (_,n): -n)
+ return [s for s,n in by_count]
+
+def form_by_random(symbol_lists):
+ # Randomize the symbols.
+ merged_symbols = uniq(s for symbols in symbol_lists
+ for s in symbols)
+ random.shuffle(merged_symbols)
+ return merged_symbols
+
+def form_by_alphabetical(symbol_lists):
+ # Alphabetize the symbols.
+ merged_symbols = list(set(s for symbols in symbol_lists for s in symbols))
+ merged_symbols.sort()
+ return merged_symbols
+
+methods = dict((name[len("form_by_"):],value)
+ for name,value in locals().items() if name.startswith("form_by_"))
+
+def genOrderFile(args):
+ parser = argparse.ArgumentParser(
+ "%prog [options] <dtrace data file directories>]")
+ parser.add_argument('input', nargs='+', help='')
+ parser.add_argument("--binary", metavar="PATH", type=str, dest="binary_path",
+ help="Path to the binary being ordered (for getting all symbols)",
+ default=None)
+ parser.add_argument("--output", dest="output_path",
+ help="path to output order file to write", default=None, required=True,
+ metavar="PATH")
+ parser.add_argument("--show-missing-symbols", dest="show_missing_symbols",
+ help="show symbols which are 'fixed up' to a valid name (requires --binary)",
+ action="store_true", default=None)
+ parser.add_argument("--output-unordered-symbols",
+ dest="output_unordered_symbols_path",
+ help="write a list of the unordered symbols to PATH (requires --binary)",
+ default=None, metavar="PATH")
+ parser.add_argument("--method", dest="method",
+ help="order file generation method to use", choices=methods.keys(),
+ default='call_order')
+ opts = parser.parse_args(args)
+
+ # If the user gave us a binary, get all the symbols in the binary by
+ # snarfing 'nm' output.
+ if opts.binary_path is not None:
+ output = subprocess.check_output(['nm', '-P', opts.binary_path])
+ lines = output.split("\n")
+ all_symbols = [ln.split(' ',1)[0]
+ for ln in lines
+ if ln.strip()]
+ print("found %d symbols in binary" % len(all_symbols))
+ all_symbols.sort()
+ else:
+ all_symbols = []
+ all_symbols_set = set(all_symbols)
+
+ # Compute the list of input files.
+ input_files = []
+ for dirname in opts.input:
+ input_files.extend(findFilesWithExtension(dirname, "dtrace"))
+
+ # Load all of the input files.
+ print("loading from %d data files" % len(input_files))
+ missing_symbols = set()
+ timestamped_symbol_lists = [
+ list(parse_dtrace_symbol_file(path, all_symbols, all_symbols_set,
+ missing_symbols, opts))
+ for path in input_files]
+
+ # Reorder each symbol list.
+ symbol_lists = []
+ for timestamped_symbols_list in timestamped_symbol_lists:
+ timestamped_symbols_list.sort()
+ symbol_lists.append([symbol for _,symbol in timestamped_symbols_list])
+
+ # Execute the desire order file generation method.
+ method = methods.get(opts.method)
+ result = list(method(symbol_lists))
+
+ # Report to the user on what percentage of symbols are present in the order
+ # file.
+ num_ordered_symbols = len(result)
+ if all_symbols:
+ print("note: order file contains %d/%d symbols (%.2f%%)" % (
+ num_ordered_symbols, len(all_symbols),
+ 100.*num_ordered_symbols/len(all_symbols)), file=sys.stderr)
+
+ if opts.output_unordered_symbols_path:
+ ordered_symbols_set = set(result)
+ with open(opts.output_unordered_symbols_path, 'w') as f:
+ f.write("\n".join(s for s in all_symbols if s not in ordered_symbols_set))
+
+ # Write the order file.
+ with open(opts.output_path, 'w') as f:
+ f.write("\n".join(result))
+ f.write("\n")
+
+ return 0
+
+commands = {'clean' : clean,
+ 'merge' : merge,
+ 'dtrace' : dtrace,
+ 'cc1' : cc1,
+ 'gen-order-file' : genOrderFile}
def main():
f = commands[sys.argv[1]]