diff options
Diffstat (limited to 'test/AST')
65 files changed, 7168 insertions, 0 deletions
diff --git a/test/AST/Inputs/module.modulemap b/test/AST/Inputs/module.modulemap new file mode 100644 index 0000000000000..a8ecb09390a25 --- /dev/null +++ b/test/AST/Inputs/module.modulemap @@ -0,0 +1 @@ +module X {} diff --git a/test/AST/Inputs/std-coroutine.h b/test/AST/Inputs/std-coroutine.h new file mode 100644 index 0000000000000..7a424f1e99cf0 --- /dev/null +++ b/test/AST/Inputs/std-coroutine.h @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value +#ifndef STD_COROUTINE_H +#define STD_COROUTINE_H + +namespace std { +namespace experimental { + +template <class Ret, typename... T> +struct coroutine_traits { using promise_type = typename Ret::promise_type; }; + +template <class Promise = void> +struct coroutine_handle { + static coroutine_handle from_address(void *); +}; +template <> +struct coroutine_handle<void> { + template <class PromiseType> + coroutine_handle(coroutine_handle<PromiseType>); + static coroutine_handle from_address(void *); +}; + +struct suspend_always { + bool await_ready() { return false; } + void await_suspend(coroutine_handle<>) {} + void await_resume() {} +}; + +struct suspend_never { + bool await_ready() { return true; } + void await_suspend(coroutine_handle<>) {} + void await_resume() {} +}; + +} // namespace experimental +} // namespace std + +#endif // STD_COROUTINE_H diff --git a/test/AST/ast-dump-arm-attr.c b/test/AST/ast-dump-arm-attr.c new file mode 100644 index 0000000000000..41328165d210f --- /dev/null +++ b/test/AST/ast-dump-arm-attr.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple arm-apple-darwin -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s + +__attribute__((interrupt)) void Test(void); +// CHECK: FunctionDecl{{.*}}Test +// CHECK-NEXT: ARMInterruptAttr diff --git a/test/AST/ast-dump-array.cpp b/test/AST/ast-dump-array.cpp new file mode 100644 index 0000000000000..bfea13534a5d5 --- /dev/null +++ b/test/AST/ast-dump-array.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -strict-whitespace %s + +void testArrayInitExpr() +{ + int a[10]; + auto l = [a]{ + }; + // CHECK: |-ArrayInitLoopExpr 0x{{[^ ]*}} <col:15> 'int [10]' + // CHECK: | `-ArrayInitIndexExpr 0x{{[^ ]*}} <<invalid sloc>> 'unsigned long' +} + +template<typename T, int Size> +class array { + T data[Size]; + + using array_T_size = T[Size]; + // CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'T [Size]' dependent <col:25, col:30> +}; + diff --git a/test/AST/ast-dump-attr.cpp b/test/AST/ast-dump-attr.cpp new file mode 100644 index 0000000000000..b0b08dd6f00ed --- /dev/null +++ b/test/AST/ast-dump-attr.cpp @@ -0,0 +1,233 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s
+
+int TestLocation
+__attribute__((unused));
+// CHECK: VarDecl{{.*}}TestLocation
+// CHECK-NEXT: UnusedAttr 0x{{[^ ]*}} <line:[[@LINE-2]]:16>
+
+int TestIndent
+__attribute__((unused));
+// CHECK: {{^}}VarDecl{{.*TestIndent[^()]*$}}
+// CHECK-NEXT: {{^}}`-UnusedAttr{{[^()]*$}}
+
+void TestAttributedStmt() {
+ switch (1) {
+ case 1:
+ [[clang::fallthrough]];
+ case 2:
+ ;
+ }
+}
+// CHECK: FunctionDecl{{.*}}TestAttributedStmt
+// CHECK: AttributedStmt
+// CHECK-NEXT: FallThroughAttr
+// CHECK-NEXT: NullStmt
+
+[[clang::warn_unused_result]] int TestCXX11DeclAttr();
+// CHECK: FunctionDecl{{.*}}TestCXX11DeclAttr
+// CHECK-NEXT: WarnUnusedResultAttr
+
+int TestAlignedNull __attribute__((aligned));
+// CHECK: VarDecl{{.*}}TestAlignedNull
+// CHECK-NEXT: AlignedAttr {{.*}} aligned
+// CHECK-NEXT: <<<NULL>>>
+
+int TestAlignedExpr __attribute__((aligned(4)));
+// CHECK: VarDecl{{.*}}TestAlignedExpr
+// CHECK-NEXT: AlignedAttr {{.*}} aligned
+// CHECK-NEXT: ConstantExpr
+// CHECK-NEXT: IntegerLiteral
+
+int TestEnum __attribute__((visibility("default")));
+// CHECK: VarDecl{{.*}}TestEnum
+// CHECK-NEXT: VisibilityAttr{{.*}} Default
+
+class __attribute__((lockable)) Mutex {
+} mu1, mu2;
+int TestExpr __attribute__((guarded_by(mu1)));
+// CHECK: VarDecl{{.*}}TestExpr
+// CHECK-NEXT: GuardedByAttr
+// CHECK-NEXT: DeclRefExpr{{.*}}mu1
+
+class Mutex TestVariadicExpr __attribute__((acquired_after(mu1, mu2)));
+// CHECK: VarDecl{{.*}}TestVariadicExpr
+// CHECK: AcquiredAfterAttr
+// CHECK-NEXT: DeclRefExpr{{.*}}mu1
+// CHECK-NEXT: DeclRefExpr{{.*}}mu2
+
+void function1(void *) {
+ int TestFunction __attribute__((cleanup(function1)));
+}
+// CHECK: VarDecl{{.*}}TestFunction
+// CHECK-NEXT: CleanupAttr{{.*}} Function{{.*}}function1
+
+void TestIdentifier(void *, int)
+__attribute__((pointer_with_type_tag(ident1,1,2)));
+// CHECK: FunctionDecl{{.*}}TestIdentifier
+// CHECK: ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag ident1
+
+void TestBool(void *, int)
+__attribute__((pointer_with_type_tag(bool1,1,2)));
+// CHECK: FunctionDecl{{.*}}TestBool
+// CHECK: ArgumentWithTypeTagAttr{{.*}}pointer_with_type_tag bool1 1 2 IsPointer
+
+void TestUnsigned(void *, int)
+__attribute__((pointer_with_type_tag(unsigned1,1,2)));
+// CHECK: FunctionDecl{{.*}}TestUnsigned
+// CHECK: ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag unsigned1 1 2
+
+void TestInt(void) __attribute__((constructor(123)));
+// CHECK: FunctionDecl{{.*}}TestInt
+// CHECK-NEXT: ConstructorAttr{{.*}} 123
+
+static int TestString __attribute__((alias("alias1")));
+// CHECK: VarDecl{{.*}}TestString
+// CHECK-NEXT: AliasAttr{{.*}} "alias1"
+
+extern struct s1 TestType
+__attribute__((type_tag_for_datatype(ident1,int)));
+// CHECK: VarDecl{{.*}}TestType
+// CHECK-NEXT: TypeTagForDatatypeAttr{{.*}} int
+
+void TestLabel() {
+L: __attribute__((unused)) int i;
+// CHECK: LabelStmt{{.*}}'L'
+// CHECK: VarDecl{{.*}}i 'int'
+// CHECK-NEXT: UnusedAttr{{.*}}
+
+M: __attribute(()) int j;
+// CHECK: LabelStmt {{.*}} 'M'
+// CHECK-NEXT: DeclStmt
+// CHECK-NEXT: VarDecl {{.*}} j 'int'
+
+N: __attribute(()) ;
+// CHECK: LabelStmt {{.*}} 'N'
+// CHECK-NEXT: NullStmt
+}
+
+namespace Test {
+extern "C" int printf(const char *format, ...);
+// CHECK: FunctionDecl{{.*}}printf
+// CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
+// CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2
+
+alignas(8) extern int x;
+extern int x;
+// CHECK: VarDecl{{.*}} x 'int'
+// CHECK: VarDecl{{.*}} x 'int'
+// CHECK-NEXT: AlignedAttr{{.*}} Inherited
+}
+
+int __attribute__((cdecl)) TestOne(void), TestTwo(void);
+// CHECK: FunctionDecl{{.*}}TestOne{{.*}}__attribute__((cdecl))
+// CHECK: FunctionDecl{{.*}}TestTwo{{.*}}__attribute__((cdecl))
+
+void func() {
+ auto Test = []() __attribute__((no_thread_safety_analysis)) {};
+ // CHECK: CXXMethodDecl{{.*}}operator() 'void () const'
+ // CHECK: NoThreadSafetyAnalysisAttr
+
+ // Because GNU's noreturn applies to the function type, and this lambda does
+ // not have a capture list, the call operator and the function pointer
+ // conversion should both be noreturn, but the method should not contain a
+ // NoReturnAttr because the attribute applied to the type.
+ auto Test2 = []() __attribute__((noreturn)) { while(1); };
+ // CHECK: CXXMethodDecl{{.*}}operator() 'void () __attribute__((noreturn)) const'
+ // CHECK-NOT: NoReturnAttr
+ // CHECK: CXXConversionDecl{{.*}}operator void (*)() __attribute__((noreturn))
+}
+
+namespace PR20930 {
+struct S {
+ struct { int Test __attribute__((deprecated)); };
+ // CHECK: FieldDecl{{.*}}Test 'int'
+ // CHECK-NEXT: DeprecatedAttr
+};
+
+void f() {
+ S s;
+ s.Test = 1;
+ // CHECK: IndirectFieldDecl{{.*}}Test 'int'
+ // CHECK: DeprecatedAttr
+}
+}
+
+struct __attribute__((objc_bridge_related(NSParagraphStyle,,))) TestBridgedRef;
+// CHECK: CXXRecordDecl{{.*}} struct TestBridgedRef
+// CHECK-NEXT: ObjCBridgeRelatedAttr{{.*}} NSParagraphStyle
+
+void TestExternalSourceSymbolAttr1()
+__attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr1
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr2()
+__attribute__((external_source_symbol(defined_in="module", language="Swift")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr2
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module"{{$}}
+
+void TestExternalSourceSymbolAttr3()
+__attribute__((external_source_symbol(generated_declaration, language="Objective-C++", defined_in="module")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr3
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Objective-C++" "module" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr4()
+__attribute__((external_source_symbol(defined_in="Some external file.cs", generated_declaration, language="C Sharp")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr4
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "C Sharp" "Some external file.cs" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr5()
+__attribute__((external_source_symbol(generated_declaration, defined_in="module", language="Swift")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
+
+namespace TestNoEscape {
+ void noescapeFunc(int *p0, __attribute__((noescape)) int *p1) {}
+ // CHECK: `-FunctionDecl{{.*}} noescapeFunc 'void (int *, __attribute__((noescape)) int *)'
+ // CHECK-NEXT: ParmVarDecl
+ // CHECK-NEXT: ParmVarDecl
+ // CHECK-NEXT: NoEscapeAttr
+}
+
+namespace TestSuppress {
+ [[gsl::suppress("at-namespace")]];
+ // CHECK: NamespaceDecl{{.*}} TestSuppress
+ // CHECK-NEXT: EmptyDecl{{.*}}
+ // CHECK-NEXT: SuppressAttr{{.*}} at-namespace
+ [[gsl::suppress("on-decl")]]
+ void TestSuppressFunction();
+ // CHECK: FunctionDecl{{.*}} TestSuppressFunction
+ // CHECK-NEXT SuppressAttr{{.*}} on-decl
+
+ void f() {
+ int *i;
+
+ [[gsl::suppress("on-stmt")]] {
+ // CHECK: AttributedStmt
+ // CHECK-NEXT: SuppressAttr{{.*}} on-stmt
+ // CHECK-NEXT: CompoundStmt
+ i = reinterpret_cast<int*>(7);
+ }
+ }
+}
+
+// Verify the order of attributes in the Ast. It must reflect the order
+// in the parsed source.
+int mergeAttrTest() __attribute__((deprecated)) __attribute__((warn_unused_result));
+int mergeAttrTest() __attribute__((annotate("test")));
+int mergeAttrTest() __attribute__((unused,no_thread_safety_analysis));
+// CHECK: FunctionDecl{{.*}} mergeAttrTest
+// CHECK-NEXT: DeprecatedAttr
+// CHECK-NEXT: WarnUnusedResultAttr
+
+// CHECK: FunctionDecl{{.*}} mergeAttrTest
+// CHECK-NEXT: DeprecatedAttr{{.*}} Inherited
+// CHECK-NEXT: WarnUnusedResultAttr{{.*}} Inherited
+// CHECK-NEXT: AnnotateAttr{{.*}}
+
+// CHECK: FunctionDecl{{.*}} mergeAttrTest
+// CHECK-NEXT: DeprecatedAttr{{.*}} Inherited
+// CHECK-NEXT: WarnUnusedResultAttr{{.*}} Inherited
+// CHECK-NEXT: AnnotateAttr{{.*}} Inherited
+// CHECK-NEXT: UnusedAttr
+// CHECK-NEXT: NoThreadSafetyAnalysisAttr
diff --git a/test/AST/ast-dump-attr.m b/test/AST/ast-dump-attr.m new file mode 100644 index 0000000000000..8775d40d99850 --- /dev/null +++ b/test/AST/ast-dump-attr.m @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s
+
+@interface NSObject
+@end
+
+[[clang::objc_exception]]
+@interface Test1 {
+// CHECK: ObjCInterfaceDecl{{.*}} Test1
+// CHECK-NEXT: ObjCExceptionAttr{{.*}}
+ [[clang::iboutlet]] NSObject *Test2;
+// CHECK: ObjCIvarDecl{{.*}} Test2
+// CHECK-NEXT: IBOutletAttr
+}
+@property (readonly) [[clang::objc_returns_inner_pointer]] void *Test3, *Test4;
+// CHECK: ObjCPropertyDecl{{.*}} Test3 'void *' readonly
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr
+// CHECK-NEXT: ObjCPropertyDecl{{.*}} Test4 'void *' readonly
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr
+
+@property (readonly) [[clang::iboutlet]] NSObject *Test5;
+// CHECK: ObjCPropertyDecl{{.*}} Test5 'NSObject *' readonly
+// CHECK-NEXT: IBOutletAttr
+
+// CHECK: ObjCMethodDecl{{.*}} implicit{{.*}} Test3
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr
+// CHECK: ObjCMethodDecl{{.*}} implicit{{.*}} Test4
+// CHECK-NEXT: ObjCReturnsInnerPointerAttr
+// CHECK: ObjCMethodDecl{{.*}} implicit{{.*}} Test5
+// CHECK-NOT: IBOutletAttr
+@end
+
+[[clang::objc_runtime_name("name")]] @protocol Test6;
+// CHECK: ObjCProtocolDecl{{.*}} Test6
+// CHECK-NEXT: ObjCRuntimeNameAttr{{.*}} "name"
+
+[[clang::objc_protocol_requires_explicit_implementation]]
+@protocol Test7
+// CHECK: ObjCProtocolDecl{{.*}} Test7
+// CHECK-NEXT: ObjCExplicitProtocolImplAttr
+@end
+
+@interface Test8
+// CHECK: ObjCInterfaceDecl{{.*}} Test8
+-(void)Test9 [[clang::ns_consumes_self]];
+// CHECK: ObjCMethodDecl{{.*}} Test9 'void'
+// CHECK-NEXT: NSConsumesSelfAttr
+-(void) [[clang::ns_consumes_self]] Test10: (int)Test11;
+// CHECK: ObjCMethodDecl{{.*}} Test10: 'void'
+// CHECK-NEXT: |-ParmVarDecl{{.*}} Test11 'int'
+// CHECK-NEXT: `-NSConsumesSelfAttr
+-(void)Test12: (int *) [[clang::noescape]] Test13 to:(int)Test14 [[clang::ns_consumes_self]];
+// CHECK: ObjCMethodDecl{{.*}} Test12:to: 'void'
+// CHECK-NEXT: |-ParmVarDecl{{.*}} Test13 'int *'
+// CHECK-NEXT: | `-NoEscapeAttr
+// CHECK-NEXT: |-ParmVarDecl{{.*}} Test14 'int'
+// CHECK-NEXT: `-NSConsumesSelfAttr
+@end
diff --git a/test/AST/ast-dump-c-attr.c b/test/AST/ast-dump-c-attr.c new file mode 100644 index 0000000000000..8452b797e2bd3 --- /dev/null +++ b/test/AST/ast-dump-c-attr.c @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux -fdouble-square-bracket-attributes -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s
+
+int Test1 [[deprecated]];
+// CHECK: VarDecl{{.*}}Test1
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:13> "" ""
+
+enum [[deprecated("Frobble")]] Test2 {
+ Test3 [[deprecated]]
+};
+// CHECK: EnumDecl{{.*}}Test2
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:8, col:28> "Frobble" ""
+// CHECK-NEXT: EnumConstantDecl{{.*}}Test3
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:11> "" ""
+
+struct [[deprecated]] Test4 {
+ [[deprecated("Frobble")]] int Test5, Test6;
+ int Test7 [[deprecated]] : 12;
+};
+// CHECK: RecordDecl{{.*}}Test4
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:10> "" ""
+// CHECK-NEXT: FieldDecl{{.*}}Test5
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" ""
+// CHECK-NEXT: FieldDecl{{.*}}Test6
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" ""
+// CHECK-NEXT: FieldDecl{{.*}}Test7
+// CHECK-NEXT: Constant{{.*}}'int'
+// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" ""
+
+struct [[deprecated]] Test8;
+// CHECK: RecordDecl{{.*}}Test8
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:10> "" ""
+
+[[deprecated]] void Test9(int Test10 [[deprecated]]);
+// CHECK: FunctionDecl{{.*}}Test9
+// CHECK-NEXT: ParmVarDecl{{.*}}Test10
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:40> "" ""
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:3> "" ""
+
+void Test11 [[deprecated]](void);
+// CHECK: FunctionDecl{{.*}}Test11
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" ""
+
+void Test12(void) [[deprecated]] {}
+// CHECK: FunctionDecl{{.*}}Test12
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:21> "" ""
diff --git a/test/AST/ast-dump-color.cpp b/test/AST/ast-dump-color.cpp new file mode 100644 index 0000000000000..8cf52049251bd --- /dev/null +++ b/test/AST/ast-dump-color.cpp @@ -0,0 +1,102 @@ +// RUN: not %clang_cc1 -triple x86_64-pc-linux -std=c++11 -ast-dump -fcolor-diagnostics %s | FileCheck --strict-whitespace %s +// REQUIRES: ansi-escape-sequences + +/// <a>Hello</a> +/// <br/> +int Test __attribute__((unused)); + +/// Comment +void TestAttributedStmt() { + switch (1) { + case 1: + [[clang::fallthrough]]; + case 2: + ; + } +} + +class __attribute__((lockable)) Mutex { + /// A variable + int var1; + /// Another variable + /// + /// Like the other variable, but different + int var2; +} mu1, mu2; +int TestExpr __attribute__((guarded_by(mu1))); + +struct Invalid { + __attribute__((noinline)) Invalid(error); +} Invalid; + +//CHECK: {{^}}[[GREEN:.\[0;1;32m]]TranslationUnitDecl[[RESET:.\[0m]][[Yellow:.\[0;33m]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]]{{$}} +//CHECK: {{^}}[[Blue:.\[0;34m]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN:.\[0;1;36m]] __int128_t[[RESET]] [[Green:.\[0;32m]]'__int128'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN]] __uint128_t[[RESET]] [[Green]]'unsigned __int128'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN]] __builtin_va_list[[RESET]] [[Green]]'__va_list_tag [1]'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]{{.*}}ast-dump-color.cpp:6:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] Test[[RESET]] [[Green]]'int'[[RESET]] +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE:.\[0;1;34m]]UnusedAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:25[[RESET]]> unused{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]]> Text=" "{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:7[[RESET]]> Name="a"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]], [[Yellow]]col:12[[RESET]]> Text="Hello"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]HTMLEndTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:13[[RESET]], [[Yellow]]col:16[[RESET]]> Name="a"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:5:4[[RESET]]> Text=" "{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:8[[RESET]]> Name="br" SelfClosing{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void ()'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]> Text=" Comment"{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:1[[RESET]]> [[Yellow]]line:18:33[[RESET]] class[[CYAN]] Mutex[[RESET]] definition{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE]]CapabilityAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:22[[RESET]]> capability "mutex"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit class[[CYAN]] Mutex[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:20:3[[RESET]], [[Yellow]]col:7[[RESET]]> [[Yellow]]col:7[[RESET]][[CYAN]] var1[[RESET]] [[Green]]'int'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:19:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]> Text=" A variable"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:24:3[[RESET]], [[Yellow]]col:7[[RESET]]> [[Yellow]]col:7[[RESET]][[CYAN]] var2[[RESET]] [[Green]]'int'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]line:23:44[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]col:22[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:22[[RESET]]> Text=" Another variable"{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:23:6[[RESET]], [[Yellow]]col:44[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:44[[RESET]]> Text=" Like the other variable, but different"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit used[[CYAN]] Mutex[[RESET]] [[Green]]'void () noexcept'[[RESET]] inline{{.*$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit constexpr[[CYAN]] Mutex[[RESET]] [[Green]]'void (const Mutex &)'[[RESET]] inline{{ .*$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'const Mutex &'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit constexpr[[CYAN]] Mutex[[RESET]] [[Green]]'void (Mutex &&)'[[RESET]] inline{{ .*$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'Mutex &&'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]> [[Yellow]]col:3[[RESET]] referenced[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]] +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]> [[Yellow]]col:8[[RESET]][[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]] +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]] +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]], [[Yellow]]col:43[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:1[[RESET]], [[Yellow]]line:30:1[[RESET]]> [[Yellow]]line:28:8[[RESET]] struct[[CYAN]] Invalid[[RESET]] definition +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit referenced struct[[CYAN]] Invalid[[RESET]] +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:3[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]] +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:37[[RESET]], [[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]col:42[[RESET]] invalid [[Green]]'int'[[RESET]] +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[BLUE]]NoInlineAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:18[[RESET]]> +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit used constexpr[[CYAN]] Invalid[[RESET]] [[Green]]'void () noexcept'[[RESET]] inline +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit constexpr[[CYAN]] Invalid[[RESET]] [[Green]]'void (const Invalid &)'[[RESET]] inline default trivial noexcept-unevaluated 0x{{[0-9a-fA-F]*}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'const Invalid &'[[RESET]] +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit constexpr[[CYAN]] Invalid[[RESET]] [[Green]]'void (Invalid &&)'[[RESET]] inline default trivial noexcept-unevaluated 0x{{[0-9a-fA-F]*}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'Invalid &&'[[RESET]] +//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:30:3[[RESET]]> [[Yellow]]col:3[[RESET]][[CYAN]] Invalid[[RESET]] [[Green]]'struct Invalid':'Invalid'[[RESET]] +//CHECK: {{^}}[[Blue]] `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'struct Invalid':'Invalid'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]] diff --git a/test/AST/ast-dump-comment.cpp b/test/AST/ast-dump-comment.cpp new file mode 100644 index 0000000000000..5bd6934d80cf5 --- /dev/null +++ b/test/AST/ast-dump-comment.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -Wdocumentation -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +/// Aaa +int TestLocation; +// CHECK: VarDecl{{.*}}TestLocation +// CHECK-NEXT: FullComment 0x{{[^ ]*}} <line:[[@LINE-3]]:4, col:7> + +/// +int TestIndent; +// CHECK: {{^VarDecl.*TestIndent[^()]*$}} +// CHECK-NEXT: {{^`-FullComment.*>$}} + +/// Aaa +int Test_TextComment; +// CHECK: VarDecl{{.*}}Test_TextComment +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" Aaa" + +/// \brief Aaa +int Test_BlockCommandComment; +// CHECK: VarDecl{{.*}}Test_BlockCommandComment +// CHECK: BlockCommandComment{{.*}} Name="brief" +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" Aaa" + +/// \param Aaa xxx +/// \param [in,out] Bbb yyy +void Test_ParamCommandComment(int Aaa, int Bbb); +// CHECK: FunctionDecl{{.*}}Test_ParamCommandComment +// CHECK: ParamCommandComment{{.*}} [in] implicitly Param="Aaa" ParamIndex=0 +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" xxx" +// CHECK: ParamCommandComment{{.*}} [in,out] explicitly Param="Bbb" ParamIndex=1 +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" yyy" + +/// \tparam Aaa xxx +template <typename Aaa> class Test_TParamCommandComment; +// CHECK: ClassTemplateDecl{{.*}}Test_TParamCommandComment +// CHECK: TParamCommandComment{{.*}} Param="Aaa" Position=<0> +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" xxx" + +/// \c Aaa +int Test_InlineCommandComment; +// CHECK: VarDecl{{.*}}Test_InlineCommandComment +// CHECK: InlineCommandComment{{.*}} Name="c" RenderMonospaced Arg[0]="Aaa" + +/// <a>Aaa</a> +/// <br/> +int Test_HTMLTagComment; +// CHECK: VarDecl{{.*}}Test_HTMLTagComment +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" " +// CHECK-NEXT: HTMLStartTagComment{{.*}} Name="a" +// CHECK-NEXT: TextComment{{.*}} Text="Aaa" +// CHECK-NEXT: HTMLEndTagComment{{.*}} Name="a" +// CHECK-NEXT: TextComment{{.*}} Text=" " +// CHECK-NEXT: HTMLStartTagComment{{.*}} Name="br" SelfClosing + +/// \verbatim +/// Aaa +/// \endverbatim +int Test_VerbatimBlockComment; +// CHECK: VarDecl{{.*}}Test_VerbatimBlockComment +// CHECK: VerbatimBlockComment{{.*}} Name="verbatim" CloseName="endverbatim" +// CHECK-NEXT: VerbatimBlockLineComment{{.*}} Text=" Aaa" + +/// \param ... More arguments +template<typename T> +void Test_TemplatedFunctionVariadic(int arg, ...); +// CHECK: FunctionTemplateDecl{{.*}}Test_TemplatedFunctionVariadic +// CHECK: ParamCommandComment{{.*}} [in] implicitly Param="..." +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" More arguments" diff --git a/test/AST/ast-dump-decl-stmts.cpp b/test/AST/ast-dump-decl-stmts.cpp new file mode 100644 index 0000000000000..3705bc5785c56 --- /dev/null +++ b/test/AST/ast-dump-decl-stmts.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -strict-whitespace %s + +void test_func() { + int a, b, c; + // CHECK: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:14> + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:7> col:7 a 'int' + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:10> col:10 b 'int' + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:13> col:13 c 'int' + void d(), e(int); + // CHECK: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:19> + // CHECK-NEXT: FunctionDecl 0x{{[^ ]*}} parent 0x{{[^ ]*}} <col:3, col:10> col:8 d 'void ()' + // CHECK-NEXT: FunctionDecl 0x{{[^ ]*}} parent 0x{{[^ ]*}} <col:3, col:18> col:13 e 'void (int)' + // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:15> col:18 'int' + int f; + // CHECK: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:7> col:7 f 'int' +} + +// FIXME: These currently do not show up as a DeclStmt. +int a, b, c; +// CHECK: VarDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:5> col:5 a 'int' +// CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:1, col:8> col:8 b 'int' +// CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:1, col:11> col:11 c 'int' +void d(), e(int); +// CHECK: FunctionDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:8> col:6 d 'void ()' +// CHECK-NEXT: FunctionDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <col:1, col:16> col:11 e 'void (int)' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:13> col:16 'int' +int f; +// CHECK: VarDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:5> col:5 f 'int' + diff --git a/test/AST/ast-dump-decl.c b/test/AST/ast-dump-decl.c new file mode 100644 index 0000000000000..e0a8b56f70a59 --- /dev/null +++ b/test/AST/ast-dump-decl.c @@ -0,0 +1,170 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -check-prefix CHECK-TU -strict-whitespace %s +// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fmodule-name=X -triple x86_64-unknown-unknown -fmodule-map-file=%S/Inputs/module.modulemap -ast-dump -ast-dump-filter Test %s -DMODULES | FileCheck -check-prefix CHECK -check-prefix CHECK-MODULES -strict-whitespace %s + +int TestLocation; +// CHECK: VarDecl 0x{{[^ ]*}} <{{.*}}:[[@LINE-1]]:1, col:5> col:5 TestLocation + +#ifdef MODULES +#pragma clang module begin X +#endif + +struct TestIndent { + int x; +}; +// CHECK: {{^}}RecordDecl{{.*TestIndent[^()]*$}} +// CHECK-NEXT: {{^}}`-FieldDecl{{.*x[^()]*$}} + +struct TestChildren { + int x; + struct y { + int z; + }; +}; +// CHECK: RecordDecl{{.*}}TestChildren +// CHECK-NEXT: FieldDecl{{.*}}x +// CHECK-NEXT: RecordDecl{{.*}}y +// CHECK-NEXT: FieldDecl{{.*}}z + +// CHECK-TU: TranslationUnitDecl + +void testLabelDecl() { + __label__ TestLabelDecl; + TestLabelDecl: goto TestLabelDecl; +} +// CHECK: LabelDecl{{.*}} TestLabelDecl + +typedef int TestTypedefDecl; +// CHECK: TypedefDecl{{.*}} TestTypedefDecl 'int' + +__module_private__ typedef int TestTypedefDeclPrivate; +// CHECK-MODULE: TypedefDecl{{.*}} TestTypedefDeclPrivate 'int' __module_private__ + +enum TestEnumDecl { + testEnumDecl +}; +// CHECK: EnumDecl{{.*}} TestEnumDecl +// CHECK-NEXT: EnumConstantDecl{{.*}} testEnumDecl + +struct TestEnumDeclAnon { + enum { + testEnumDeclAnon + } e; +}; +// CHECK: RecordDecl{{.*}} TestEnumDeclAnon +// CHECK-NEXT: EnumDecl{{.*> .*$}} + +enum TestEnumDeclForward; +// CHECK: EnumDecl{{.*}} TestEnumDeclForward + +__module_private__ enum TestEnumDeclPrivate; +// CHECK-MODULE: EnumDecl{{.*}} TestEnumDeclPrivate __module_private__ + +struct TestRecordDecl { + int i; +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDecl +// CHECK-NEXT: FieldDecl + +struct TestRecordDeclEmpty { +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclEmpty + +struct TestRecordDeclAnon1 { + struct { + } testRecordDeclAnon1; +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclAnon1 +// CHECK-NEXT: RecordDecl{{.*}} struct + +struct TestRecordDeclAnon2 { + struct { + }; +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclAnon2 +// CHECK-NEXT: RecordDecl{{.*}} struct + +struct TestRecordDeclForward; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclForward + +__module_private__ struct TestRecordDeclPrivate; +// CHECK-MODULE: RecordDecl{{.*}} struct TestRecordDeclPrivate __module_private__ + +enum testEnumConstantDecl { + TestEnumConstantDecl, + TestEnumConstantDeclInit = 1 +}; +// CHECK: EnumConstantDecl{{.*}} TestEnumConstantDecl 'int' +// CHECK: EnumConstantDecl{{.*}} TestEnumConstantDeclInit 'int' +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral + +struct testIndirectFieldDecl { + struct { + int TestIndirectFieldDecl; + }; +}; +// CHECK: IndirectFieldDecl{{.*}} TestIndirectFieldDecl 'int' +// CHECK-NEXT: Field{{.*}} '' +// CHECK-NEXT: Field{{.*}} 'TestIndirectFieldDecl' + +// FIXME: It would be nice to dump the enum and its enumerators. +int TestFunctionDecl(int x, enum { e } y) { + return x; +} +// CHECK: FunctionDecl{{.*}} TestFunctionDecl 'int (int, enum {{.*}})' +// CHECK-NEXT: ParmVarDecl{{.*}} x +// CHECK-NEXT: ParmVarDecl{{.*}} y +// CHECK-NEXT: CompoundStmt + +// FIXME: It would be nice to 'Enum' and 'e'. +int TestFunctionDecl2(enum Enum { e } x) { return x; } +// CHECK: FunctionDecl{{.*}} TestFunctionDecl2 'int (enum {{.*}})' +// CHECK-NEXT: ParmVarDecl{{.*}} x +// CHECK-NEXT: CompoundStmt + + +int TestFunctionDeclProto(int x); +// CHECK: FunctionDecl{{.*}} TestFunctionDeclProto 'int (int)' +// CHECK-NEXT: ParmVarDecl{{.*}} x + +extern int TestFunctionDeclSC(); +// CHECK: FunctionDecl{{.*}} TestFunctionDeclSC 'int ()' extern + +inline int TestFunctionDeclInline(); +// CHECK: FunctionDecl{{.*}} TestFunctionDeclInline 'int ()' inline + +struct testFieldDecl { + int TestFieldDecl; + int TestFieldDeclWidth : 1; + __module_private__ int TestFieldDeclPrivate; +}; +// CHECK: FieldDecl{{.*}} TestFieldDecl 'int' +// CHECK: FieldDecl{{.*}} TestFieldDeclWidth 'int' +// CHECK-NEXT: ConstantExpr +// CHECK-NEXT: IntegerLiteral +// CHECK-MODULE: FieldDecl{{.*}} TestFieldDeclPrivate 'int' __module_private__ + +int TestVarDecl; +// CHECK: VarDecl{{.*}} TestVarDecl 'int' + +extern int TestVarDeclSC; +// CHECK: VarDecl{{.*}} TestVarDeclSC 'int' extern + +__thread int TestVarDeclThread; +// CHECK: VarDecl{{.*}} TestVarDeclThread 'int' tls{{$}} + +__module_private__ int TestVarDeclPrivate; +// CHECK-MODULE: VarDecl{{.*}} TestVarDeclPrivate 'int' __module_private__ + +int TestVarDeclInit = 0; +// CHECK: VarDecl{{.*}} TestVarDeclInit 'int' +// CHECK-NEXT: IntegerLiteral + +void testParmVarDecl(int TestParmVarDecl); +// CHECK: ParmVarDecl{{.*}} TestParmVarDecl 'int' + +#ifdef MODULES +#pragma clang module end +#endif + diff --git a/test/AST/ast-dump-decl.cpp b/test/AST/ast-dump-decl.cpp new file mode 100644 index 0000000000000..6386d340eb791 --- /dev/null +++ b/test/AST/ast-dump-decl.cpp @@ -0,0 +1,569 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
+
+class testEnumDecl {
+ enum class TestEnumDeclScoped;
+ enum TestEnumDeclFixed : int;
+};
+// CHECK: EnumDecl{{.*}} class TestEnumDeclScoped 'int'
+// CHECK: EnumDecl{{.*}} TestEnumDeclFixed 'int'
+
+class testFieldDecl {
+ int TestFieldDeclInit = 0;
+};
+// CHECK: FieldDecl{{.*}} TestFieldDeclInit 'int'
+// CHECK-NEXT: IntegerLiteral
+
+namespace testVarDeclNRVO {
+ class A { };
+ A foo() {
+ A TestVarDeclNRVO;
+ return TestVarDeclNRVO;
+ }
+}
+// CHECK: VarDecl{{.*}} TestVarDeclNRVO 'testVarDeclNRVO::A' nrvo
+
+void testParmVarDeclInit(int TestParmVarDeclInit = 0);
+// CHECK: ParmVarDecl{{.*}} TestParmVarDeclInit 'int'
+// CHECK-NEXT: IntegerLiteral{{.*}}
+
+namespace TestNamespaceDecl {
+ int i;
+}
+// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl
+// CHECK-NEXT: VarDecl
+
+namespace TestNamespaceDecl {
+ int j;
+}
+// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl
+// CHECK-NEXT: original Namespace
+// CHECK-NEXT: VarDecl
+
+inline namespace TestNamespaceDeclInline {
+}
+// CHECK: NamespaceDecl{{.*}} TestNamespaceDeclInline inline
+
+namespace testUsingDirectiveDecl {
+ namespace A {
+ }
+}
+namespace TestUsingDirectiveDecl {
+ using namespace testUsingDirectiveDecl::A;
+}
+// CHECK: NamespaceDecl{{.*}} TestUsingDirectiveDecl
+// CHECK-NEXT: UsingDirectiveDecl{{.*}} Namespace{{.*}} 'A'
+
+namespace testNamespaceAlias {
+ namespace A {
+ }
+}
+namespace TestNamespaceAlias = testNamespaceAlias::A;
+// CHECK: NamespaceAliasDecl{{.*}} TestNamespaceAlias
+// CHECK-NEXT: Namespace{{.*}} 'A'
+
+using TestTypeAliasDecl = int;
+// CHECK: TypeAliasDecl{{.*}} TestTypeAliasDecl 'int'
+
+namespace testTypeAliasTemplateDecl {
+ template<typename T> class A;
+ template<typename T> using TestTypeAliasTemplateDecl = A<T>;
+}
+// CHECK: TypeAliasTemplateDecl{{.*}} TestTypeAliasTemplateDecl
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A<T>'
+
+namespace testCXXRecordDecl {
+ class TestEmpty {};
+// CHECK: CXXRecordDecl{{.*}} class TestEmpty
+// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+// CHECK-NEXT: DefaultConstructor exists trivial constexpr
+// CHECK-NEXT: CopyConstructor simple trivial has_const_param
+// CHECK-NEXT: MoveConstructor exists simple trivial
+// CHECK-NEXT: CopyAssignment trivial has_const_param
+// CHECK-NEXT: MoveAssignment exists simple trivial
+// CHECK-NEXT: Destructor simple irrelevant trivial
+
+ class A { };
+ class B { };
+ class TestCXXRecordDecl : virtual A, public B {
+ int i;
+ };
+}
+// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl
+// CHECK-NEXT: DefinitionData{{$}}
+// CHECK-NEXT: DefaultConstructor exists non_trivial
+// CHECK-NEXT: CopyConstructor simple non_trivial has_const_param
+// CHECK-NEXT: MoveConstructor exists simple non_trivial
+// CHECK-NEXT: CopyAssignment non_trivial has_const_param
+// CHECK-NEXT: MoveAssignment exists simple non_trivial
+// CHECK-NEXT: Destructor simple irrelevant trivial
+// CHECK-NEXT: virtual private 'testCXXRecordDecl::A'
+// CHECK-NEXT: public 'testCXXRecordDecl::B'
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl
+// CHECK-NEXT: FieldDecl
+
+template<class...T>
+class TestCXXRecordDeclPack : public T... {
+};
+// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
+// CHECK: public 'T'...
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
+
+thread_local int TestThreadLocalInt;
+// CHECK: TestThreadLocalInt {{.*}} tls_dynamic
+
+class testCXXMethodDecl {
+ virtual void TestCXXMethodDeclPure() = 0;
+ void TestCXXMethodDeclDelete() = delete;
+ void TestCXXMethodDeclThrow() throw();
+ void TestCXXMethodDeclThrowType() throw(int);
+};
+// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPure 'void ()' virtual pure
+// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclDelete 'void ()' delete
+// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrow 'void () throw()'
+// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrowType 'void () throw(int)'
+
+namespace testCXXConstructorDecl {
+ class A { };
+ class TestCXXConstructorDecl : public A {
+ int I;
+ TestCXXConstructorDecl(A &a, int i) : A(a), I(i) { }
+ TestCXXConstructorDecl(A &a) : TestCXXConstructorDecl(a, 0) { }
+ };
+}
+// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}'
+// CHECK-NEXT: ParmVarDecl{{.*}} a
+// CHECK-NEXT: ParmVarDecl{{.*}} i
+// CHECK-NEXT: CXXCtorInitializer{{.*}}A
+// CHECK-NEXT: Expr
+// CHECK: CXXCtorInitializer{{.*}}I
+// CHECK-NEXT: Expr
+// CHECK: CompoundStmt
+// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}'
+// CHECK-NEXT: ParmVarDecl{{.*}} a
+// CHECK-NEXT: CXXCtorInitializer{{.*}}TestCXXConstructorDecl
+// CHECK-NEXT: CXXConstructExpr{{.*}}TestCXXConstructorDecl
+
+class TestCXXDestructorDecl {
+ ~TestCXXDestructorDecl() { }
+};
+// CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void () noexcept'
+// CHECK-NEXT: CompoundStmt
+
+// Test that the range of a defaulted members is computed correctly.
+class TestMemberRanges {
+public:
+ TestMemberRanges() = default;
+ TestMemberRanges(const TestMemberRanges &Other) = default;
+ TestMemberRanges(TestMemberRanges &&Other) = default;
+ ~TestMemberRanges() = default;
+ TestMemberRanges &operator=(const TestMemberRanges &Other) = default;
+ TestMemberRanges &operator=(TestMemberRanges &&Other) = default;
+};
+void SomeFunction() {
+ TestMemberRanges A;
+ TestMemberRanges B(A);
+ B = A;
+ A = static_cast<TestMemberRanges &&>(B);
+ TestMemberRanges C(static_cast<TestMemberRanges &&>(A));
+}
+// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:30>
+// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:59>
+// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:54>
+// CHECK: CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:31>
+// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:70>
+// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:65>
+
+class TestCXXConversionDecl {
+ operator int() { return 0; }
+};
+// CHECK: CXXConversionDecl{{.*}} operator int 'int ()'
+// CHECK-NEXT: CompoundStmt
+
+namespace TestStaticAssertDecl {
+ static_assert(true, "msg");
+}
+// CHECK: NamespaceDecl{{.*}} TestStaticAssertDecl
+// CHECK-NEXT: StaticAssertDecl{{.*> .*$}}
+// CHECK-NEXT: CXXBoolLiteralExpr
+// CHECK-NEXT: StringLiteral
+
+namespace testFunctionTemplateDecl {
+ class A { };
+ class B { };
+ class C { };
+ class D { };
+ template<typename T> void TestFunctionTemplate(T) { }
+
+ // implicit instantiation
+ void bar(A a) { TestFunctionTemplate(a); }
+
+ // explicit specialization
+ template<> void TestFunctionTemplate(B);
+
+ // explicit instantiation declaration
+ extern template void TestFunctionTemplate(C);
+
+ // explicit instantiation definition
+ template void TestFunctionTemplate(D);
+}
+// CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+// CHECK-NEXT: ParmVarDecl{{.*}} 'T'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
+// CHECK-NEXT: TemplateArgument
+// CHECK-NEXT: ParmVarDecl
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' {{.*}}B
+// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}C
+// CHECK-NEXT: TemplateArgument
+// CHECK-NEXT: ParmVarDecl
+// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}D
+// CHECK-NEXT: TemplateArgument
+// CHECK-NEXT: ParmVarDecl
+// CHECK-NEXT: CompoundStmt
+// CHECK: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}B
+// CHECK-NEXT: TemplateArgument
+// CHECK-NEXT: ParmVarDecl
+
+namespace testClassTemplateDecl {
+ class A { };
+ class B { };
+ class C { };
+ class D { };
+
+ template<typename T> class TestClassTemplate {
+ public:
+ TestClassTemplate();
+ ~TestClassTemplate();
+ int j();
+ int i;
+ };
+
+ // implicit instantiation
+ TestClassTemplate<A> a;
+
+ // explicit specialization
+ template<> class TestClassTemplate<B> {
+ int j;
+ };
+
+ // explicit instantiation declaration
+ extern template class TestClassTemplate<C>;
+
+ // explicit instantiation definition
+ template class TestClassTemplate<D>;
+
+ // partial explicit specialization
+ template<typename T1, typename T2> class TestClassTemplatePartial {
+ int i;
+ };
+ template<typename T1> class TestClassTemplatePartial<T1, A> {
+ int j;
+ };
+
+ template<typename T = int> struct TestTemplateDefaultType;
+ template<typename T> struct TestTemplateDefaultType { };
+
+ template<int I = 42> struct TestTemplateDefaultNonType;
+ template<int I> struct TestTemplateDefaultNonType { };
+
+ template<template<typename> class TT = TestClassTemplate> struct TestTemplateTemplateDefaultType;
+ template<template<typename> class TT> struct TestTemplateTemplateDefaultType { };
+}
+// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK-NEXT: AccessSpecDecl{{.*}} public
+// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
+// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
+// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
+// CHECK-NEXT: FieldDecl{{.*}} i
+// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
+// CHECK: TemplateArgument{{.*}}A
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK-NEXT: AccessSpecDecl{{.*}} public
+// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
+// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
+// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
+// CHECK-NEXT: FieldDecl{{.*}} i
+// CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
+// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
+// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
+
+// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
+// CHECK-NEXT: DefinitionData
+// CHECK: TemplateArgument{{.*}}B
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK-NEXT: FieldDecl{{.*}} j
+
+// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
+// CHECK: TemplateArgument{{.*}}C
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK-NEXT: AccessSpecDecl{{.*}} public
+// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
+// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
+// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
+// CHECK-NEXT: FieldDecl{{.*}} i
+
+// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
+// CHECK: TemplateArgument{{.*}}D
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+// CHECK-NEXT: AccessSpecDecl{{.*}} public
+// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
+// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
+// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
+// CHECK-NEXT: FieldDecl{{.*}} i
+
+// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial
+// CHECK: TemplateArgument
+// CHECK-NEXT: TemplateArgument{{.*}}A
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial
+// CHECK-NEXT: FieldDecl{{.*}} j
+
+// CHECK: ClassTemplateDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} {{.*}} TestTemplateDefaultType
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: TemplateArgument type 'int'
+// CHECK-NEXT: inherited from TemplateTypeParm 0x{{[^ ]*}} 'T'
+
+// CHECK: ClassTemplateDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} {{.*}} TestTemplateDefaultNonType
+// CHECK-NEXT: NonTypeTemplateParmDecl
+// CHECK-NEXT: TemplateArgument expr
+// CHECK-NEXT: inherited from NonTypeTemplateParm 0x{{[^ ]*}} 'I' 'int'
+// CHECK-NEXT: ConstantExpr
+// CHECK-NEXT: IntegerLiteral
+
+// CHECK: ClassTemplateDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} {{.*}} TestTemplateTemplateDefaultType
+// CHECK-NEXT: TemplateTemplateParmDecl
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: TemplateArgument
+// CHECK-NEXT: inherited from TemplateTemplateParm 0x{{[^ ]*}} 'TT'
+
+// PR15220 dump instantiation only once
+namespace testCanonicalTemplate {
+ class A {};
+
+ template<typename T> void TestFunctionTemplate(T);
+ template<typename T> void TestFunctionTemplate(T);
+ void bar(A a) { TestFunctionTemplate(a); }
+ // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
+ // CHECK-NEXT: TemplateTypeParmDecl
+ // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+ // CHECK-NEXT: ParmVarDecl{{.*}} 'T'
+ // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
+ // CHECK-NEXT: TemplateArgument
+ // CHECK-NEXT: ParmVarDecl
+ // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
+ // CHECK-NEXT: TemplateTypeParmDecl
+ // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
+ // CHECK-NEXT: ParmVarDecl{{.*}} 'T'
+ // CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate'
+ // CHECK-NOT: TemplateArgument
+
+ template<typename T1> class TestClassTemplate {
+ template<typename T2> friend class TestClassTemplate;
+ };
+ TestClassTemplate<A> a;
+ // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
+ // CHECK-NEXT: TemplateTypeParmDecl
+ // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+ // CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
+ // CHECK-NEXT: FriendDecl
+ // CHECK-NEXT: ClassTemplateDecl{{.*}} TestClassTemplate
+ // CHECK-NEXT: TemplateTypeParmDecl
+ // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+ // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
+ // CHECK: TemplateArgument{{.*}}A
+ // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
+}
+
+template <class T>
+class TestClassScopeFunctionSpecialization {
+ template<class U> void foo(U a) { }
+ template<> void foo<int>(int a) { }
+};
+// CHECK: ClassScopeFunctionSpecializationDecl
+// CHECK-NEXT: CXXMethod{{.*}} foo 'void (int)'
+// CHECK-NEXT: ParmVarDecl
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: TemplateArgument{{.*}} 'int'
+
+namespace TestTemplateTypeParmDecl {
+ template<typename ... T, class U = int> void foo();
+}
+// CHECK: NamespaceDecl{{.*}} TestTemplateTypeParmDecl
+// CHECK-NEXT: FunctionTemplateDecl
+// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename depth 0 index 0 ... T
+// CHECK-NEXT: TemplateTypeParmDecl{{.*}} class depth 0 index 1 U
+// CHECK-NEXT: TemplateArgument type 'int'
+
+namespace TestNonTypeTemplateParmDecl {
+ template<int I = 1, int ... J> void foo();
+}
+// CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl
+// CHECK-NEXT: FunctionTemplateDecl
+// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I
+// CHECK-NEXT: TemplateArgument expr
+// CHECK-NEXT: ConstantExpr{{.*}} 'int'
+// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1
+// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J
+
+namespace TestTemplateTemplateParmDecl {
+ template<typename T> class A;
+ template <template <typename> class T = A, template <typename> class ... U> void foo();
+}
+// CHECK: NamespaceDecl{{.*}} TestTemplateTemplateParmDecl
+// CHECK: FunctionTemplateDecl
+// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T
+// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
+// CHECK-NEXT: TemplateArgument{{.*}} template A
+// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U
+// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
+
+namespace TestTemplateArgument {
+ template<typename> class A { };
+ template<template<typename> class ...> class B { };
+ int foo();
+
+ template<typename> class testType { };
+ template class testType<int>;
+ // CHECK: ClassTemplateSpecializationDecl{{.*}} class testType
+ // CHECK: TemplateArgument{{.*}} type 'int'
+
+ template<int fp(void)> class testDecl { };
+ template class testDecl<foo>;
+ // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl
+ // CHECK: TemplateArgument{{.*}} decl
+ // CHECK-NEXT: Function{{.*}}foo
+
+ template class testDecl<nullptr>;
+ // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl
+ // CHECK: TemplateArgument{{.*}} nullptr
+
+ template<int> class testIntegral { };
+ template class testIntegral<1>;
+ // CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral
+ // CHECK: TemplateArgument{{.*}} integral 1
+
+ template<template<typename> class> class testTemplate { };
+ template class testTemplate<A>;
+ // CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate
+ // CHECK: TemplateArgument{{.*}} A
+
+ template<template<typename> class ...T> class C {
+ B<T...> testTemplateExpansion;
+ };
+ // FIXME: Need TemplateSpecializationType dumping to test TemplateExpansion.
+
+ template<int, int = 0> class testExpr;
+ template<int I> class testExpr<I> { };
+ // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr
+ // CHECK: TemplateArgument{{.*}} expr
+ // CHECK-NEXT: DeclRefExpr{{.*}}I
+
+ template<int, int ...> class testPack { };
+ template class testPack<0, 1, 2>;
+ // CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack
+ // CHECK: TemplateArgument{{.*}} integral 0
+ // CHECK-NEXT: TemplateArgument{{.*}} pack
+ // CHECK-NEXT: TemplateArgument{{.*}} integral 1
+ // CHECK-NEXT: TemplateArgument{{.*}} integral 2
+}
+
+namespace testUsingDecl {
+ int i;
+}
+namespace TestUsingDecl {
+ using testUsingDecl::i;
+}
+// CHECK: NamespaceDecl{{.*}} TestUsingDecl
+// CHECK-NEXT: UsingDecl{{.*}} testUsingDecl::i
+// CHECK-NEXT: UsingShadowDecl{{.*}} Var{{.*}} 'i' 'int'
+
+namespace testUnresolvedUsing {
+ class A { };
+ template<class T> class B {
+ public:
+ A a;
+ };
+ template<class T> class TestUnresolvedUsing : public B<T> {
+ using typename B<T>::a;
+ using B<T>::a;
+ };
+}
+// CHECK: CXXRecordDecl{{.*}} TestUnresolvedUsing
+// CHECK: UnresolvedUsingTypenameDecl{{.*}} B<T>::a
+// CHECK: UnresolvedUsingValueDecl{{.*}} B<T>::a
+
+namespace TestLinkageSpecDecl {
+ extern "C" void test1();
+ extern "C++" void test2();
+}
+// CHECK: NamespaceDecl{{.*}} TestLinkageSpecDecl
+// CHECK-NEXT: LinkageSpecDecl{{.*}} C
+// CHECK-NEXT: FunctionDecl
+// CHECK-NEXT: LinkageSpecDecl{{.*}} C++
+// CHECK-NEXT: FunctionDecl
+
+class TestAccessSpecDecl {
+public:
+private:
+protected:
+};
+// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl
+// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl
+// CHECK-NEXT: AccessSpecDecl{{.*}} public
+// CHECK-NEXT: AccessSpecDecl{{.*}} private
+// CHECK-NEXT: AccessSpecDecl{{.*}} protected
+
+template<typename T> class TestFriendDecl {
+ friend int foo();
+ friend class A;
+ friend T;
+};
+// CHECK: CXXRecord{{.*}} TestFriendDecl
+// CHECK: CXXRecord{{.*}} TestFriendDecl
+// CHECK-NEXT: FriendDecl
+// CHECK-NEXT: FunctionDecl{{.*}} foo
+// CHECK-NEXT: FriendDecl{{.*}} 'class A':'A'
+// CHECK-NEXT: FriendDecl{{.*}} 'T'
+
+namespace TestFileScopeAsmDecl {
+ asm("ret");
+}
+// CHECK: NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}}
+// CHECK: FileScopeAsmDecl{{.*> .*$}}
+// CHECK-NEXT: StringLiteral
+
+namespace TestFriendDecl2 {
+ void f();
+ struct S {
+ friend void f();
+ };
+}
+// CHECK: NamespaceDecl [[TestFriendDecl2:0x.*]] <{{.*}}> {{.*}} TestFriendDecl2
+// CHECK: |-FunctionDecl [[TestFriendDecl2_f:0x.*]] <{{.*}}> {{.*}} f 'void ()'
+// CHECK: `-CXXRecordDecl {{.*}} struct S
+// CHECK: |-CXXRecordDecl {{.*}} struct S
+// CHECK: `-FriendDecl
+// CHECK: `-FunctionDecl {{.*}} parent [[TestFriendDecl2]] prev [[TestFriendDecl2_f]] <{{.*}}> {{.*}} f 'void ()'
+
+namespace Comment {
+ extern int Test;
+ /// Something here.
+ extern int Test;
+ extern int Test;
+}
+
+// CHECK: VarDecl {{.*}} Test 'int' extern
+// CHECK-NOT: FullComment
+// CHECK: VarDecl {{.*}} Test 'int' extern
+// CHECK: `-FullComment
+// CHECK: `-ParagraphComment
+// CHECK: `-TextComment
+// CHECK: VarDecl {{.*}} Test 'int' extern
+// CHECK-NOT: FullComment
diff --git a/test/AST/ast-dump-decl.m b/test/AST/ast-dump-decl.m new file mode 100644 index 0000000000000..7f114dd7cb28e --- /dev/null +++ b/test/AST/ast-dump-decl.m @@ -0,0 +1,153 @@ +// RUN: %clang_cc1 -Wno-unused -fblocks -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +@protocol P +@end + +@interface A +@end + +@interface TestObjCIvarDecl : A +@end + +@implementation TestObjCIvarDecl { + int varDefault; + @private int varPrivate; + @protected int varProtected; + @public int varPublic; + @package int varPackage; +} +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCIvarDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCIvarDecl' +// CHECK-NEXT: ObjCIvarDecl{{.*}} varDefault 'int' private +// CHECK-NEXT: ObjCIvarDecl{{.*}} varPrivate 'int' private +// CHECK-NEXT: ObjCIvarDecl{{.*}} varProtected 'int' protected +// CHECK-NEXT: ObjCIvarDecl{{.*}} varPublic 'int' public +// CHECK-NEXT: ObjCIvarDecl{{.*}} varPackage 'int' package + +@interface testObjCMethodDecl : A { +} +- (int) TestObjCMethodDecl: (int)i, ...; +// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int' +// CHECK-NEXT: ParmVarDecl{{.*}} i 'int' +// CHECK-NEXT: ... +@end + +@implementation testObjCMethodDecl +- (int) TestObjCMethodDecl: (int)i, ... { + return 0; +} +// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int' +// CHECK-NEXT: ImplicitParamDecl{{.*}} self +// CHECK-NEXT: ImplicitParamDecl{{.*}} _cmd +// CHECK-NEXT: ParmVarDecl{{.*}} i 'int' +// CHECK-NEXT: ... +// CHECK-NEXT: CompoundStmt +@end + +@protocol TestObjCProtocolDecl +- (void) foo; +@end +// CHECK: ObjCProtocolDecl{{.*}} TestObjCProtocolDecl +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +@interface TestObjCClass : A <P> +- (void) foo; +@end +// CHECK: ObjCInterfaceDecl{{.*}} TestObjCClass +// CHECK-NEXT: super ObjCInterface{{.*}} 'A' +// CHECK-NEXT: ObjCImplementation{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCProtocol{{.*}} 'P' +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +@implementation TestObjCClass : A { + int i; +} +- (void) foo { +} +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCClass +// CHECK-NEXT: super ObjCInterface{{.*}} 'A' +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCIvarDecl{{.*}} i +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +@interface TestObjCClass (TestObjCCategoryDecl) <P> +- (void) bar; +@end +// CHECK: ObjCCategoryDecl{{.*}} TestObjCCategoryDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCCategoryImpl{{.*}} 'TestObjCCategoryDecl' +// CHECK-NEXT: ObjCProtocol{{.*}} 'P' +// CHECK-NEXT: ObjCMethodDecl{{.*}} bar + +@interface TestGenericInterface<T> : A<P> { +} +@end +// CHECK: ObjCInterfaceDecl{{.*}} TestGenericInterface +// CHECK-NEXT: -super ObjCInterface {{.+}} 'A' +// CHECK-NEXT: -ObjCProtocol {{.+}} 'P' +// CHECK-NEXT: -ObjCTypeParamDecl {{.+}} <col:33> col:33 T 'id':'id' + +@implementation TestObjCClass (TestObjCCategoryDecl) +- (void) bar { +} +@end +// CHECK: ObjCCategoryImplDecl{{.*}} TestObjCCategoryDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCCategory{{.*}} 'TestObjCCategoryDecl' +// CHECK-NEXT: ObjCMethodDecl{{.*}} bar + +@compatibility_alias TestObjCCompatibleAliasDecl A; +// CHECK: ObjCCompatibleAliasDecl{{.*}} TestObjCCompatibleAliasDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'A' + +@interface TestObjCProperty: A +@property(getter=getterFoo, setter=setterFoo:) int foo; +@property int bar; +@end +// CHECK: ObjCInterfaceDecl{{.*}} TestObjCProperty +// CHECK: ObjCPropertyDecl{{.*}} foo 'int' assign readwrite atomic unsafe_unretained +// CHECK-NEXT: getter ObjCMethod{{.*}} 'getterFoo' +// CHECK-NEXT: setter ObjCMethod{{.*}} 'setterFoo:' +// CHECK-NEXT: ObjCPropertyDecl{{.*}} bar 'int' assign readwrite atomic unsafe_unretained +// CHECK-NEXT: ObjCMethodDecl{{.*}} getterFoo +// CHECK-NEXT: ObjCMethodDecl{{.*}} setterFoo: +// CHECK-NEXT: ParmVarDecl{{.*}} foo +// CHECK-NEXT: ObjCMethodDecl{{.*}} bar +// CHECK-NEXT: ObjCMethodDecl{{.*}} setBar: +// CHECK-NEXT: ParmVarDecl{{.*}} bar + +@implementation TestObjCProperty { + int i; +} +@synthesize foo=i; +@synthesize bar; +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCProperty +// CHECK: ObjCPropertyImplDecl{{.*}} foo synthesize +// CHECK-NEXT: ObjCProperty{{.*}} 'foo' +// CHECK-NEXT: ObjCIvar{{.*}} 'i' 'int' +// CHECK-NEXT: ObjCIvarDecl{{.*}} bar 'int' synthesize private +// CHECK-NEXT: ObjCPropertyImplDecl{{.*}} bar synthesize +// CHECK-NEXT: ObjCProperty{{.*}} 'bar' +// CHECK-NEXT: ObjCIvar{{.*}} 'bar' 'int' + +void TestBlockDecl(int x) { + ^(int y, ...){ x; }; +} +// CHECK: FunctionDecl{{.*}}TestBlockDecl +// CHECK: BlockDecl +// CHECK-NEXT: ParmVarDecl{{.*}} y 'int' +// CHECK-NEXT: ... +// CHECK-NEXT: capture ParmVar{{.*}} 'x' 'int' +// CHECK-NEXT: CompoundStmt + +@interface B ++ (int) foo; +@end + +void f() { + __typeof__(B.foo) Test; +} +// CHECK: VarDecl{{.*}}Test 'typeof (B.foo)':'int' diff --git a/test/AST/ast-dump-decl.mm b/test/AST/ast-dump-decl.mm new file mode 100644 index 0000000000000..be245f7ef5cdf --- /dev/null +++ b/test/AST/ast-dump-decl.mm @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -Wno-unused -fblocks -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +@interface A +@end + +@interface TestObjCImplementation : A +@end + +@implementation TestObjCImplementation : A { + struct X { + int i; + } X; +} +- (void) foo { +} +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCImplementation +// CHECK-NEXT: super ObjCInterface{{.*}} 'A' +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCImplementation' +// CHECK-NEXT: CXXCtorInitializer{{.*}} 'X' +// CHECK-NEXT: CXXConstructExpr +// CHECK-NEXT: ObjCIvarDecl{{.*}} X +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +// @() boxing expressions. +template <typename T> +struct BoxingTest { + static id box(T value) { + return @(value); + } +}; + +// CHECK: ObjCBoxedExpr{{.*}} '<dependent type>'{{$}} diff --git a/test/AST/ast-dump-expr.c b/test/AST/ast-dump-expr.c new file mode 100644 index 0000000000000..6011ab7975b09 --- /dev/null +++ b/test/AST/ast-dump-expr.c @@ -0,0 +1,339 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu11 -ast-dump %s | FileCheck -strict-whitespace %s + +void Comma(void) { + 1, 2, 3; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> 'int' ',' + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:3, col:6> 'int' ',' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:3> 'int' 1 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:6> 'int' 2 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 3 +} + +void Assignment(int a) { + a = 12; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '=' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:7> 'int' 12 + + a += a; + // CHECK: CompoundAssignOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '+=' ComputeLHSTy='int' ComputeResultTy='int' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' +} + +void Conditionals(int a) { + a ? 0 : 1; + // CHECK: ConditionalOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:7> 'int' 0 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 1 + + a ?: 0; + // CHECK: BinaryConditionalOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: OpaqueValueExpr 0x{{[^ ]*}} <col:3> 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: OpaqueValueExpr 0x{{[^ ]*}} <col:3> 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 0 +} + +void BinaryOperators(int a, int b) { + // Logical operators + a || b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '||' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a && b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '&&' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + // Bitwise operators + a | b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '|' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a ^ b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '^' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a & b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '&' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + // Equality operators + a == b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '==' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a != b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '!=' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + // Relational operators + a < b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '<' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a > b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '>' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a <= b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '<=' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a >= b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '>=' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + // Bit shifting operators + a << b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '<<' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a >> b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'int' '>>' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + // Additive operators + a + b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '+' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a - b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '-' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + // Multiplicative operators + a * b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '*' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a / b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '/' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' + + a % b; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> 'int' '%' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> 'int' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int' +} + +void UnaryOperators(int a, int *b) { + // Cast operators + (float)a; + // CHECK: CStyleCastExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> 'float' <IntegralToFloating> + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + // ++, --, and ~ are covered elsewhere. + + -a; + // CHECK: UnaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:4> 'int' prefix '-' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + +a; + // CHECK: UnaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:4> 'int' prefix '+' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + &a; + // CHECK: UnaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:4> 'int *' prefix '&' cannot overflow + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + *b; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:3, col:4> 'int' lvalue prefix '*' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'b' 'int *' + + !a; + // CHECK: UnaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:4> 'int' prefix '!' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + sizeof a; + // CHECK: UnaryExprOrTypeTraitExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> 'unsigned long' sizeof + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + sizeof(int); + // CHECK: UnaryExprOrTypeTraitExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13> 'unsigned long' sizeof 'int' + + _Alignof(int); + // FIXME: Uses C++ spelling for alignof in C mode. + // CHECK: UnaryExprOrTypeTraitExpr 0x{{[^ ]*}} <line:[[@LINE-2]]:3, col:15> 'unsigned long' alignof 'int' +} + +struct S { + int a; +}; + +void PostfixOperators(int *a, struct S b, struct S *c) { + a[0]; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: ArraySubscriptExpr 0x{{[^ ]*}} <col:3, col:6> 'int' lvalue + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int *' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:5> 'int' 0 + + UnaryOperators(*a, a); + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:23> 'void' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'void (int, int *)' Function 0x{{[^ ]*}} 'UnaryOperators' 'void (int, int *)' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:18, col:19> 'int' lvalue prefix '*' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:19> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:22> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int *' + + b.a; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:5> 'int' lvalue .a 0x{{[^ ]*}} + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'struct S':'struct S' lvalue ParmVar 0x{{[^ ]*}} 'b' 'struct S':'struct S' + + c->a; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:6> 'int' lvalue ->a 0x{{[^ ]*}} + // CHECK: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'struct S *' lvalue ParmVar 0x{{[^ ]*}} 'c' 'struct S *' + + // Postfix ++ and -- are covered elsewhere. + + (int [4]){1, 2, 3, 4, }; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: CompoundLiteralExpr 0x{{[^ ]*}} <col:3, col:25> 'int [4]' lvalue + // CHECK-NEXT: InitListExpr 0x{{[^ ]*}} <col:12, col:25> 'int [4]' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:13> 'int' 1 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:16> 'int' 2 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:19> 'int' 3 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:22> 'int' 4 + + (struct S){1}; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: CompoundLiteralExpr 0x{{[^ ]*}} <col:3, col:15> 'struct S':'struct S' lvalue + // CHECK-NEXT: InitListExpr 0x{{[^ ]*}} <col:13, col:15> 'struct S':'struct S' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 1 +} + +enum E { One }; + +void PrimaryExpressions(int a) { + a; + // CHECK: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + 'a'; + // CHECK: CharacterLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'int' 97 + + L'a'; + // CHECK: CharacterLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'int' 97 + + "a"; + // ImplicitCastExpr + // CHECK: StringLiteral 0x{{[^ ]*}} <col:3> 'char [2]' lvalue "a" + + L"a"; + // ImplicitCastExpr + // CHECK: StringLiteral 0x{{[^ ]*}} <col:3> 'int [2]' lvalue L"a" + + u8"a"; + // ImplicitCastExpr + // CHECK: StringLiteral 0x{{[^ ]*}} <col:3> 'char [2]' lvalue u8"a" + + U"a"; + // ImplicitCastExpr + // CHECK: StringLiteral 0x{{[^ ]*}} <col:3> 'unsigned int [2]' lvalue U"a" + + u"a"; + // ImplicitCastExpr + // CHECK: StringLiteral 0x{{[^ ]*}} <col:3> 'unsigned short [2]' lvalue u"a" + + 1; + // CHECK: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'int' 1 + + 1u; + // CHECK: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'unsigned int' 1 + + 1ll; + // CHECK: IntegerLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'long long' 1 + + 1.0; + // CHECK: FloatingLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'double' {{1\.[0]*e[\+]?[0]+}} + + 1.0f; + // CHECK: FloatingLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'float' {{1\.[0]*e[\+]?[0]+}} + + 1.0l; + // CHECK: FloatingLiteral 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'long double' {{1\.[0]*e[\+]?[0]+}} + + One; + // CHECK: DeclRefExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'int' EnumConstant 0x{{[^ ]*}} 'One' 'int' + + (a); + // CHECK: ImplicitCastExpr + // CHECK-NEXT: ParenExpr 0x{{[^ ]*}} <col:3, col:5> 'int' lvalue + // CHECK: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int' lvalue ParmVar 0x{{[^ ]*}} 'a' 'int' + + // Generic selection expressions are covered elsewhere. +} diff --git a/test/AST/ast-dump-expr.cpp b/test/AST/ast-dump-expr.cpp new file mode 100644 index 0000000000000..5d668aad4ae97 --- /dev/null +++ b/test/AST/ast-dump-expr.cpp @@ -0,0 +1,553 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -ast-dump %s | FileCheck -strict-whitespace %s + +namespace std { +using size_t = decltype(sizeof(0)); + +class type_info { +public: + virtual ~type_info(); + bool operator==(const type_info& rhs) const noexcept; + bool operator!=(const type_info& rhs) const noexcept; + type_info(const type_info& rhs) = delete; // cannot be copied + type_info& operator=(const type_info& rhs) = delete; // cannot be copied +}; + +class bad_typeid { +public: + bad_typeid() noexcept; + bad_typeid(const bad_typeid&) noexcept; + virtual ~bad_typeid(); + bad_typeid& operator=(const bad_typeid&) noexcept; + const char* what() const noexcept; +}; +} // namespace std +void *operator new(std::size_t, void *ptr); + +struct S { + virtual ~S() = default; + + void func(int); + template <typename Ty> + Ty foo(); + + int i; +}; + +struct T : S {}; + +template <typename> +struct U {}; + +void Throw() { + throw 12; + // CHECK: CXXThrowExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> 'void' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 12 + + throw; + // CHECK: CXXThrowExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3> 'void' +} + +void PointerToMember(S obj1, S *obj2, int S::* data, void (S::*call)(int)) { + obj1.*data; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> 'int' lvalue '.*' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'obj1' 'S' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:9> 'int S::*' lvalue ParmVar 0x{{[^ ]*}} 'data' 'int S::*' + + obj2->*data; + // CHECK: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> 'int' lvalue '->*' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'obj2' 'S *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'int S::*' lvalue ParmVar 0x{{[^ ]*}} 'data' 'int S::*' + + (obj1.*call)(12); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> 'void' + // CHECK-NEXT: ParenExpr 0x{{[^ ]*}} <col:3, col:14> '<bound member function type>' + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:4, col:10> '<bound member function type>' '.*' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'S' lvalue ParmVar 0x{{[^ ]*}} 'obj1' 'S' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'void (S::*)(int)' lvalue ParmVar 0x{{[^ ]*}} 'call' 'void (S::*)(int)' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:16> 'int' 12 + + (obj2->*call)(12); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:19> 'void' + // CHECK-NEXT: ParenExpr 0x{{[^ ]*}} <col:3, col:15> '<bound member function type>' + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:4, col:11> '<bound member function type>' '->*' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'obj2' 'S *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:11> 'void (S::*)(int)' lvalue ParmVar 0x{{[^ ]*}} 'call' 'void (S::*)(int)' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:17> 'int' 12 +} + +void Casting(const S *s) { + // FIXME: The cast expressions contain "struct S" instead of "S". + + const_cast<S *>(s); + // CHECK: CXXConstCastExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:20> 'S *' const_cast<struct S *> <NoOp> + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:19> 'const S *' <LValueToRValue> part_of_explicit_cast + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:19> 'const S *' lvalue ParmVar 0x{{[^ ]*}} 's' 'const S *' + + static_cast<const T *>(s); + // CHECK: CXXStaticCastExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:27> 'const T *' static_cast<const struct T *> <BaseToDerived (S)> + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:26> 'const S *' <LValueToRValue> part_of_explicit_cast + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:26> 'const S *' lvalue ParmVar 0x{{[^ ]*}} 's' 'const S *' + + dynamic_cast<const T *>(s); + // CHECK: CXXDynamicCastExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:28> 'const T *' dynamic_cast<const struct T *> <Dynamic> + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:27> 'const S *' <LValueToRValue> part_of_explicit_cast + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:27> 'const S *' lvalue ParmVar 0x{{[^ ]*}} 's' 'const S *' + + reinterpret_cast<const int *>(s); + // CHECK: CXXReinterpretCastExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:34> 'const int *' reinterpret_cast<const int *> <BitCast> + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:33> 'const S *' <LValueToRValue> part_of_explicit_cast + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:33> 'const S *' lvalue ParmVar 0x{{[^ ]*}} 's' 'const S *' +} + +template <typename... Ts> +void UnaryExpressions(int *p) { + sizeof...(Ts); + // CHECK: SizeOfPackExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> 'unsigned long' 0x{{[^ ]*}} Ts + + noexcept(p - p); + // CHECK: CXXNoexceptExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:17> 'bool' + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:12, col:16> 'long' '-' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' + + ::new int; + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> 'int *' global Function 0x{{[^ ]*}} 'operator new' 'void *(unsigned long)' + + new (int); + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> 'int *' Function 0x{{[^ ]*}} 'operator new' 'void *(unsigned long)' + + new int{12}; + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13> 'int *' Function 0x{{[^ ]*}} 'operator new' 'void *(unsigned long)' + // CHECK-NEXT: InitListExpr 0x{{[^ ]*}} <col:10, col:13> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 + + new int[2]; + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> 'int *' array Function 0x{{[^ ]*}} 'operator new[]' 'void *(unsigned long)' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 2 + + new int[2]{1, 2}; + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> 'int *' array Function 0x{{[^ ]*}} 'operator new[]' 'void *(unsigned long)' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 2 + // CHECK-NEXT: InitListExpr 0x{{[^ ]*}} <col:13, col:18> 'int [2]' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 1 + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:17> 'int' 2 + + new (p) int; + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> 'int *' Function 0x{{[^ ]*}} 'operator new' 'void *(std::size_t, void *)' + // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void *' <BitCast> + // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <LValueToRValue> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' + + new (p) int{12}; + // CHECK: CXXNewExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:17> 'int *' Function 0x{{[^ ]*}} 'operator new' 'void *(std::size_t, void *)' + // CHECK-NEXT: InitListExpr 0x{{[^ ]*}} <col:14, col:17> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:15> 'int' 12 + // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void *' <BitCast> + // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int *' <LValueToRValue> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' + + ::delete p; + // CHECK: CXXDeleteExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> 'void' global Function 0x{{[^ ]*}} 'operator delete' 'void (void *) noexcept' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' + + delete [] p; + // CHECK: CXXDeleteExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13> 'void' array Function 0x{{[^ ]*}} 'operator delete[]' 'void (void *) noexcept' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:13> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *' +} + +void PostfixExpressions(S a, S *p, U<int> *r) { + a.func(0); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:5> '<bound member function type>' .func 0x{{[^ ]*}} + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:10> 'int' 0 + + p->func(0); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:6> '<bound member function type>' ->func 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'S *' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 0 + + // FIXME: there is no mention that this used the template keyword. + p->template foo<int>(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:24> 'int':'int' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:22> '<bound member function type>' ->foo 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'S *' + + // FIXME: there is no mention that this used the template keyword. + a.template foo<float>(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:25> 'float':'float' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:23> '<bound member function type>' .foo 0x{{[^ ]*}} + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S' + + p->~S(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:7> '<bound member function type>' ->~S 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'S *' + + a.~S(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:6> '<bound member function type>' .~S 0x{{[^ ]*}} + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S' + + // FIXME: there seems to be no way to distinguish the construct below from + // the construct above. + a.~decltype(a)(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:5> '<bound member function type>' .~S 0x{{[^ ]*}} + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S' + + // FIXME: similarly, there is no way to distinguish the construct below from + // the p->~S() case. + p->::S::~S(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:14> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:12> '<bound member function type>' ->~S 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'S *' + + // FIXME: there is no mention that this used the template keyword. + r->template U<int>::~U(); + // CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:26> 'void' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:24> '<bound member function type>' ->~U 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'U<int> *' lvalue ParmVar 0x{{[^ ]*}} 'r' 'U<int> *' + + typeid(a); + // CHECK: CXXTypeidExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> 'const std::type_info' lvalue + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S' + + // FIXME: no type information is printed for the argument. + typeid(S); + // CHECK: CXXTypeidExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> 'const std::type_info' lvalue +} + +template <typename... Ts> +void PrimaryExpressions(Ts... a) { + struct V { + void f() { + this; + // CHECK: CXXThisExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:7> 'V *' this + [this]{}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:7, col:14> + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:7> col:7 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:8> col:8 implicit 'V *' + // CHECK-NEXT: CXXMethodDecl + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' this + + [*this]{}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:7, col:15> + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:7> col:7 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:8> col:8 implicit 'V' + // CHECK-NEXT: CXXMethodDecl + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:8> 'NULL TYPE' + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:8> '<dependent type>' prefix '*' cannot overflow + // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' this + } + }; + + int b, c; + + [](){}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:6, col:8> col:3 operator() 'auto () const' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit __invoke 'auto ()' static inline + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:7, col:8> + + [a...]{}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:4> col:4 implicit 'Ts...' + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:10> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:4> 'NULL TYPE' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'Ts...' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:9, col:10> + + [=]{}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:5, col:7> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:6, col:7> + + [=] { return b; }; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:19> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:5, col:19> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:9, col:16> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'const int' lvalue Var 0x{{[^ ]*}} 'b' 'int' + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:7, col:19> + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:9, col:16> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'const int' lvalue Var 0x{{[^ ]*}} 'b' 'int' + + [&]{}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:5, col:7> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:6, col:7> + + [&] { return c; }; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:19> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:5, col:19> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:9, col:16> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'int' lvalue Var 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:7, col:19> + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:9, col:16> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'int' lvalue Var 0x{{[^ ]*}} 'c' 'int' + + [b, &c]{ return b + c; }; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:26> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:4> col:4 implicit 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:8> col:8 implicit 'int &' + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:9, col:26> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:12, col:23> + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:19, col:23> 'int' '+' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:19> 'const int' lvalue Var 0x{{[^ ]*}} 'b' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:23> 'int' lvalue Var 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'int' lvalue Var 0x{{[^ ]*}} 'b' 'int' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> 'int' lvalue Var 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:10, col:26> + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:12, col:23> + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:19, col:23> 'int' '+' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:19> 'const int' lvalue Var 0x{{[^ ]*}} 'b' 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:23> 'int' lvalue Var 0x{{[^ ]*}} 'c' 'int' + + [a..., x = 12]{}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:4> col:4 implicit 'Ts...' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:10> col:10 implicit 'int':'int' + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:16, col:18> col:3 operator() 'auto () const -> auto' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:4> 'NULL TYPE' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'Ts...' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 12 + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18> + + []() constexpr {}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:19> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:19> col:3 constexpr operator() 'auto () const' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit __invoke 'auto ()' static inline + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:18, col:19> + + []() mutable {}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:17> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:17> col:3 operator() 'auto ()' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit __invoke 'auto ()' static inline + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:16, col:17> + + []() noexcept {}; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:18> col:3 operator() 'auto () const noexcept' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit __invoke 'auto () noexcept' static inline + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18> + + []() -> int { return 0; }; + // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:27> '(lambda at {{.*}}:[[@LINE-1]]:3)' + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition + // CHECK-NEXT: DefinitionData lambda + // CHECK-NEXT: DefaultConstructor + // CHECK-NEXT: CopyConstructor + // CHECK-NEXT: MoveConstructor + // CHECK-NEXT: CopyAssignment + // CHECK-NEXT: MoveAssignment + // CHECK-NEXT: Destructor + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:11, col:27> col:3 operator() 'auto () const -> int' inline + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:17, col:24> + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:24> 'int' 0 + // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit constexpr operator int (*)() 'auto (*() const)() -> int' inline + // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit __invoke 'auto () -> int' static inline + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:15, col:27> + // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:17, col:24> + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:24> 'int' 0 + + (a + ...); + // CHECK: CXXFoldExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> '<dependent type>' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'Ts...' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' + // CHECK-NEXT: <<<NULL>>> + + (... + a); + // CHECK: CXXFoldExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> '<dependent type>' + // CHECK-NEXT: <<<NULL>>> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> 'Ts...' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' + + (a + ... + b); + // CHECK: CXXFoldExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> '<dependent type>' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:4> 'Ts...' lvalue ParmVar 0x{{[^ ]*}} 'a' 'Ts...' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int' lvalue Var 0x{{[^ ]*}} 'b' 'int' +} + + +namespace NS { +struct X {}; +void f(X); +void y(...); +} // namespace NS + +// CHECK-LABEL: FunctionDecl 0x{{[^ ]*}} {{.*}}ADLCall 'void ()' +void ADLCall() { + NS::X x; + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void' adl{{$}} + f(x); + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void' adl{{$}} + y(x); +} + +// CHECK-LABEL: FunctionDecl 0x{{[^ ]*}} {{.*}}NonADLCall 'void ()' +void NonADLCall() { + NS::X x; + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void'{{$}} + NS::f(x); +} + +// CHECK-LABEL: FunctionDecl 0x{{[^ ]*}} {{.*}}NonADLCall2 'void ()' +void NonADLCall2() { + NS::X x; + using NS::f; + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void'{{$}} + f(x); + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void' adl{{$}} + y(x); +} + +namespace test_adl_call_three { +using namespace NS; +// CHECK-LABEL: FunctionDecl 0x{{[^ ]*}} {{.*}}NonADLCall3 'void ()' +void NonADLCall3() { + X x; + // CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void'{{$}} + f(x); +} +} // namespace test_adl_call_three
\ No newline at end of file diff --git a/test/AST/ast-dump-funcs.cpp b/test/AST/ast-dump-funcs.cpp new file mode 100644 index 0000000000000..62ae9648dde04 --- /dev/null +++ b/test/AST/ast-dump-funcs.cpp @@ -0,0 +1,124 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -strict-whitespace %s + +struct R { + R() = default; + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> col:3 used constexpr R 'void () noexcept' default trivial + ~R() {} // not trivial + // CHECK: CXXDestructorDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:3 used ~R 'void () noexcept' + R(const R&) = delete; + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:22> col:3 R 'void (const R &)' delete trivial + R(R&&) = default; + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> col:3 constexpr R 'void (R &&)' default trivial noexcept-unevaluated + + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-10]]:8> col:8 implicit operator= 'R &(const R &)' inline default_delete trivial noexcept-unevaluated +}; + +struct S { + int i, j; + R r; + + S() : i(0), j(0) {} + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:21> col:3 S 'void ()' + // CHECK-NEXT: CXXCtorInitializer Field 0x{{[^ ]*}} 'i' 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 0 + // CHECK-NEXT: CXXCtorInitializer Field 0x{{[^ ]*}} 'j' 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:17> 'int' 0 + // CHECK-NEXT: CXXCtorInitializer Field 0x{{[^ ]*}} 'r' 'R' + // CHECK-NEXT: CXXConstructExpr 0x{{[^ ]*}} <col:3> 'R' 'void () noexcept' + // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:20, col:21> + + void a(); + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> col:8 a 'void ()' + void b() const; + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> col:8 b 'void () const' + void c() volatile; + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> col:8 c 'void () volatile' + void d() &; + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> col:8 d 'void () &' + void e() &&; + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:12> col:8 e 'void () &&' + virtual void f(float, int = 12); + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:33> col:16 f 'void (float, int)' virtual + // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:18> col:23 'float' + // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:25, col:31> col:29 'int' cinit + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:31> 'int' 12 + + virtual void g() = 0; + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:22> col:16 g 'void ()' virtual pure + + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <line:[[@LINE-33]]:8> col:8 implicit S 'void (const S &)' inline default_delete noexcept-unevaluated + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <col:8> col:8 implicit constexpr S 'void (S &&)' inline default noexcept-unevaluated + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <col:8> col:8 implicit operator= 'S &(const S &)' inline default_delete noexcept-unevaluated + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <col:8> col:8 implicit operator= 'S &(S &&)' inline default_delete noexcept-unevaluated + // CHECK: CXXDestructorDecl 0x{{[^ ]*}} <col:8> col:8 implicit ~S 'void ()' inline default noexcept-unevaluated +}; + +struct T : S { // T is not referenced, but S is + void f(float, int = 100) override; + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:28> col:8 f 'void (float, int)' + // CHECK-NEXT: Overrides: [ 0x{{[^ ]*}} S::f 'void (float, int)' ] + // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:10> col:15 'float' + // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:17, col:23> col:21 'int' cinit + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:23> 'int' 100 + // CHECK-NEXT: OverrideAttr + + // CHECK: CXXConstructorDecl 0x{{[^ ]*}} <line:[[@LINE-9]]:8> col:8 implicit T 'void (const T &)' inline default_delete noexcept-unevaluated + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <col:8> col:8 implicit operator= 'T &(const T &)' inline default_delete noexcept-unevaluated + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <col:8> col:8 implicit operator= 'T &(T &&)' inline default_delete noexcept-unevaluated + // CHECK: CXXDestructorDecl 0x{{[^ ]*}} <col:8> col:8 implicit ~T 'void ()' inline default noexcept-unevaluated +}; + +struct U { + void f(); + // CHECK: CXXMethodDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> col:8 f 'void ()' +}; +void U::f() {} // parent +// CHECK: CXXMethodDecl 0x{{[^ ]*}} parent 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:14> col:9 f 'void ()' +// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:13, col:14> + +void a1(); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:9> col:6 used a1 'void ()' +void a2(void); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:13> col:6 a2 'void ()' +void b(int a, int b); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:20> col:6 b 'void (int, int)' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:8, col:12> col:12 a 'int' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:15, col:19> col:19 b 'int' +void c(int a, int b = 12); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:25> col:6 c 'void (int, int)' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:8, col:12> col:12 a 'int' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:15, col:23> col:19 b 'int' cinit +// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:23> 'int' 12 +constexpr void d(void); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:22> col:16 constexpr d 'void ()' +static void e(void); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:19> col:13 e 'void ()' static +extern void f(void); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:19> col:13 f 'void ()' extern +extern "C" void g(void); +// CHECK: LinkageSpecDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:23> col:8 C +// CHECK: FunctionDecl 0x{{[^ ]*}} <col:12, col:23> col:17 g 'void ()' +inline void h(void); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:19> col:13 h 'void ()' inline +void i(void) noexcept; +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:14> col:6 i 'void () noexcept' +void j(void) noexcept(false); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:28> col:6 j 'void () noexcept(false)' +void k(void) noexcept(1); +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:24> col:6 k 'void () noexcept(1)' +template <typename T> +T l(T&); +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:7> col:3 l +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-3]]:11, col:20> col:20 referenced typename depth 0 index 0 T +// CHECK-NEXT: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-3]]:1, col:7> col:3 l 'T (T &)' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:5, col:6> col:7 'T &' + +void m(int) {} +// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:14> col:6 m 'void (int)' +// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:8> col:11 'int' +// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:13, col:14> + +int main() { + // CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:5 main 'int ()' + a1(); // Causes this to be marked 'used' +} diff --git a/test/AST/ast-dump-invalid.cpp b/test/AST/ast-dump-invalid.cpp new file mode 100644 index 0000000000000..8f7e6eb14e5e3 --- /dev/null +++ b/test/AST/ast-dump-invalid.cpp @@ -0,0 +1,62 @@ +// RUN: not %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s
+
+namespace TestInvalidRParenOnCXXUnresolvedConstructExpr {
+template <class T>
+void f(T i, T j) {
+ return T (i, j;
+}
+}
+
+// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidRParenOnCXXUnresolvedConstructExpr
+// CHECK-NEXT: `-FunctionTemplateDecl
+// CHECK-NEXT: |-TemplateTypeParmDecl
+// CHECK-NEXT: `-FunctionDecl
+// CHECK-NEXT: |-ParmVarDecl
+// CHECK-NEXT: |-ParmVarDecl
+// CHECK-NEXT: `-CompoundStmt
+// CHECK-NEXT: `-ReturnStmt
+// CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} <col:10, col:16> 'T'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <col:13> 'T' lvalue ParmVar {{.*}} 'i' 'T'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:16> 'T' lvalue ParmVar {{.*}} 'j' 'T'
+
+
+namespace TestInvalidIf {
+int g(int i) {
+ if (invalid_condition)
+ return 4;
+ else
+ return i;
+}
+}
+// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidIf
+// CHECK-NEXT: `-FunctionDecl
+// CHECK-NEXT: |-ParmVarDecl
+// CHECK-NEXT: `-CompoundStmt
+// CHECK-NEXT: `-IfStmt {{.*}} <line:25:3, line:28:12>
+// CHECK-NEXT: |-OpaqueValueExpr {{.*}} <<invalid sloc>> 'bool'
+// CHECK-NEXT: |-ReturnStmt {{.*}} <line:26:5, col:12>
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:12> 'int' 4
+// CHECK-NEXT: `-ReturnStmt {{.*}} <line:28:5, col:12>
+// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:12> 'int' <LValueToRValue>
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:12> 'int' lvalue ParmVar {{.*}} 'i' 'int'
+
+namespace TestInvalidFunctionDecl {
+struct Str {
+ double foo1(double, invalid_type);
+};
+double Str::foo1(double, invalid_type)
+{ return 45; }
+}
+// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl
+// CHECK-NEXT: |-CXXRecordDecl {{.*}} <line:44:1, line:46:1> line:44:8 struct Str definition
+// CHECK: | |-CXXRecordDecl {{.*}} <col:1, col:8> col:8 implicit struct Str
+// CHECK-NEXT: | `-CXXMethodDecl {{.*}} <line:45:4, col:36> col:11 invalid foo1 'double (double, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16> col:22 'double'
+// CHECK-NEXT: | `-ParmVarDecl {{.*}} <col:24, <invalid sloc>> col:36 invalid 'int'
+// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}} <line:47:1, line:48:14> line:47:13 invalid foo1 'double (double, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:18> col:24 'double'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:26, <invalid sloc>> col:38 invalid 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <line:48:1, col:14>
+// CHECK-NEXT: `-ReturnStmt {{.*}} <col:3, col:10>
+// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:10> 'double' <IntegralToFloating>
+// CHECK-NEXT: `-IntegerLiteral {{.*}} <col:10> 'int' 45
diff --git a/test/AST/ast-dump-lookups.cpp b/test/AST/ast-dump-lookups.cpp new file mode 100644 index 0000000000000..2d235010cb735 --- /dev/null +++ b/test/AST/ast-dump-lookups.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix DECLS %s +// RUN: %clang_cc1 -std=c++11 -ast-dump-lookups -ast-dump-filter Test %s | FileCheck -check-prefix LOOKUPS %s +// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter Test %s | FileCheck -check-prefix DECLS-LOOKUPS %s +// RUN: %clang_cc1 -std=c++11 -DPRAGMA -fsyntax-only %s 2>&1 | FileCheck -check-prefix PRAGMA %s + +namespace Test { + typedef int T; + extern int a; + int a = 0; +} + +#ifdef PRAGMA +#pragma clang __debug dump Test +// PRAGMA: lookup results for Test: +// PRAGMA-NEXT: NamespaceDecl {{.*}} Test +// PRAGMA-NEXT: |-TypedefDecl {{.*}} T 'int' +// PRAGMA-NEXT: | `-BuiltinType {{.*}} 'int' +// PRAGMA-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern +// PRAGMA-NEXT: `-VarDecl {{.*}} prev [[EXTERN_A]] {{.*}} a 'int' cinit +// PRAGMA-NEXT: `-IntegerLiteral {{.*}} 'int' 0 +#endif + +namespace Test { } + +// DECLS: Dumping Test: +// DECLS-NEXT: NamespaceDecl {{.*}} Test +// DECLS-NEXT: |-TypedefDecl {{.*}} T 'int' +// DECLS-NEXT: | `-BuiltinType {{.*}} 'int' +// DECLS-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern +// DECLS-NEXT: `-VarDecl {{.*}} prev [[EXTERN_A]] {{.*}} a 'int' cinit +// DECLS-NEXT: `-IntegerLiteral {{.*}} 'int' 0 +// +// DECLS: Dumping Test: +// DECLS-NEXT: NamespaceDecl {{.*}} Test + +// LOOKUPS: Dumping Test: +// LOOKUPS-NEXT: StoredDeclsMap Namespace {{.*}} 'Test' +// LOOKUPS: DeclarationName 'a' +// LOOKUPS-NEXT: `-Var {{.*}} 'a' 'int' +// +// LOOKUPS: Dumping Test: +// LOOKUPS-NEXT: Lookup map is in primary DeclContext + +// DECLS-LOOKUPS: Dumping Test: +// DECLS-LOOKUPS-NEXT: StoredDeclsMap Namespace {{.*}} 'Test' +// DECLS-LOOKUPS: -DeclarationName 'a' +// DECLS-LOOKUPS-NEXT: `-Var [[A:[^ ]*]] 'a' 'int' +// DECLS-LOOKUPS-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern +// DECLS-LOOKUPS-NEXT: `-VarDecl [[A]] prev [[EXTERN_A]] {{.*}} a 'int' cinit +// DECLS-LOOKUPS-NEXT: `-IntegerLiteral {{.*}} 'int' 0 +// +// DECLS-LOOKUPS: Dumping Test: +// DECLS-LOOKUPS-NEXT: Lookup map is in primary DeclContext diff --git a/test/AST/ast-dump-msp430-attr.c b/test/AST/ast-dump-msp430-attr.c new file mode 100644 index 0000000000000..3ccb3bdb705f2 --- /dev/null +++ b/test/AST/ast-dump-msp430-attr.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple msp430-unknown-unknown -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s + +__attribute__((interrupt(12))) void Test(void); +// CHECK: FunctionDecl{{.*}}Test +// CHECK-NEXT: MSP430InterruptAttr diff --git a/test/AST/ast-dump-pipe.cl b/test/AST/ast-dump-pipe.cl new file mode 100644 index 0000000000000..ceed2f6f8992a --- /dev/null +++ b/test/AST/ast-dump-pipe.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple spir64 -cl-std=CL2.0 -ast-dump -ast-dump-filter pipetype %s | FileCheck -strict-whitespace %s +typedef pipe int pipetype; +// CHECK: PipeType {{.*}} 'read_only pipe int' +// CHECK-NEXT: BuiltinType {{.*}} 'int' + +typedef read_only pipe int pipetype2; +// CHECK: PipeType {{.*}} 'read_only pipe int' +// CHECK-NEXT: BuiltinType {{.*}} 'int' + +typedef write_only pipe int pipetype3; +// CHECK: PipeType {{.*}} 'write_only pipe int' +// CHECK-NEXT: BuiltinType {{.*}} 'int' diff --git a/test/AST/ast-dump-record-definition-data.cpp b/test/AST/ast-dump-record-definition-data.cpp new file mode 100644 index 0000000000000..37ed54b1dee12 --- /dev/null +++ b/test/AST/ast-dump-record-definition-data.cpp @@ -0,0 +1,190 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump %s | FileCheck -strict-whitespace %s + +void f() { + auto IsNotGenericLambda = [](){}; + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <col:29> col:29 implicit class definition + // CHECK-NOT: DefinitionData {{.*}}generic{{.*}} + // CHECK-NEXT: DefinitionData {{.*}}lambda{{.*}} + auto IsGenericLambda = [](auto){}; + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <col:26> col:26 implicit class definition + // CHECK-NEXT: DefinitionData {{.*}}generic{{.*}}lambda{{.*}} +} + +struct CanPassInRegisters { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CanPassInRegisters definition + // CHECK-NEXT: DefinitionData {{.*}}pass_in_registers{{.*}} + CanPassInRegisters(const CanPassInRegisters&) = default; +}; + +struct CantPassInRegisters { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CantPassInRegisters definition + // CHECK-NOT: DefinitionData {{.*}}pass_in_registers{{.*}} + CantPassInRegisters(const CantPassInRegisters&) = delete; +}; + +struct IsEmpty { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct IsEmpty definition + // CHECK-NEXT: DefinitionData {{.*}}empty{{.*}} +}; + +struct IsNotEmpty { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotEmpty definition + // CHECK-NOT: DefinitionData {{.*}}empty{{.*}} + int a; +}; + +struct IsAggregate { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsAggregate definition + // CHECK-NEXT: DefinitionData {{.*}}aggregate{{.*}} + int a; +}; + +struct IsNotAggregate { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:1> line:[[@LINE-1]]:8 struct IsNotAggregate definition + // CHECK-NOT: DefinitionData {{.*}}aggregate{{.*}} +private: + int a; +}; + +struct IsStandardLayout { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsStandardLayout definition + // CHECK-NEXT: DefinitionData {{.*}}standard_layout{{.*}} + void f(); +}; + +struct IsNotStandardLayout { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotStandardLayout definition + // CHECK-NOT: DefinitionData {{.*}}standard_layout{{.*}} + virtual void f(); +}; + +struct IsTriviallyCopyable { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct IsTriviallyCopyable definition + // CHECK-NEXT: DefinitionData {{.*}}trivially_copyable{{.*}} +}; + +struct IsNotTriviallyCopyable { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotTriviallyCopyable definition + // CHECK-NOT: DefinitionData {{.*}}trivially_copyable{{.*}} + IsNotTriviallyCopyable(const IsNotTriviallyCopyable&) {} +}; + +struct IsPOD { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsPOD definition + // CHECK-NEXT: DefinitionData {{.*}}pod{{.*}} + int a; +}; + +struct IsNotPOD { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotPOD definition + // CHECK-NOT: DefinitionData {{.*}}pod{{.*}} + int &a; +}; + +struct IsTrivial { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsTrivial definition + // CHECK-NEXT: DefinitionData {{.*}}trivial {{.*}} + IsTrivial() = default; +}; + +struct IsNotTrivial { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotTrivial definition + // CHECK-NOT: DefinitionData {{.*}}trivial {{.*}} + IsNotTrivial() {} +}; + +struct IsPolymorphic { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsPolymorphic definition + // CHECK-NEXT: DefinitionData {{.*}}polymorphic{{.*}} + virtual void f(); +}; + +struct IsNotPolymorphic { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotPolymorphic definition + // CHECK-NOT: DefinitionData {{.*}}polymorphic{{.*}} + void f(); +}; + +struct IsAbstract { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsAbstract definition + // CHECK-NEXT: DefinitionData {{.*}}abstract{{.*}} + virtual void f() = 0; +}; + +struct IsNotAbstract { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotAbstract definition + // CHECK-NOT: DefinitionData {{.*}}abstract{{.*}} + virtual void f(); +}; + +struct IsLiteral { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsLiteral definition + // CHECK-NEXT: DefinitionData {{.*}}literal{{.*}} + ~IsLiteral() = default; +}; + +struct IsNotLiteral { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotLiteral definition + // CHECK-NOT: DefinitionData {{.*}}literal{{.*}} + ~IsNotLiteral() {} +}; + +struct HasUserDeclaredConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct HasUserDeclaredConstructor definition + // CHECK-NEXT: DefinitionData {{.*}}has_user_declared_ctor{{.*}} + HasUserDeclaredConstructor() {} +}; + +struct HasNoUserDeclaredConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct HasNoUserDeclaredConstructor definition + // CHECK-NOT: DefinitionData {{.*}}has_user_declared_ctor{{.*}} +}; + +struct HasConstexprNonCopyMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct HasConstexprNonCopyMoveConstructor definition + // CHECK-NEXT: DefinitionData {{.*}}has_constexpr_non_copy_move_ctor{{.*}} + constexpr HasConstexprNonCopyMoveConstructor() {} +}; + +struct HasNoConstexprNonCopyMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct HasNoConstexprNonCopyMoveConstructor definition + // CHECK-NOT: DefinitionData {{.*}}has_constexpr_non_copy_move_ctor{{.*}} + HasNoConstexprNonCopyMoveConstructor() {} +}; + +struct HasMutableFields { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct HasMutableFields definition + // CHECK-NEXT: DefinitionData {{.*}}has_mutable_fields{{.*}} + mutable int i; +}; + +struct HasNoMutableFields { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct HasNoMutableFields definition + // CHECK-NOT: DefinitionData {{.*}}has_mutable_fields{{.*}} + int i; +}; + +struct HasVariantMembers { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+5]]:1> line:[[@LINE-1]]:8 struct HasVariantMembers definition + // CHECK-NEXT: DefinitionData {{.*}}has_variant_members{{.*}} + union { + int i; + }; +}; + +struct HasNoVariantMembers { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct HasNoVariantMembers definition + // CHECK-NOT: DefinitionData {{.*}}has_variant_members{{.*}} +}; + +struct AllowsConstDefaultInit { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct AllowsConstDefaultInit definition + // CHECK-NEXT: DefinitionData {{.*}}can_const_default_init{{.*}} + int i = 12; +}; + +struct DoesNotAllowConstDefaultInit { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotAllowConstDefaultInit definition + // CHECK-NOT: DefinitionData {{.*}}can_const_default_init{{.*}} + int i; +}; diff --git a/test/AST/ast-dump-records.c b/test/AST/ast-dump-records.c new file mode 100644 index 0000000000000..e24c6047794d1 --- /dev/null +++ b/test/AST/ast-dump-records.c @@ -0,0 +1,150 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -strict-whitespace %s + +struct A; +// CHECK: RecordDecl 0x{{[^ ]*}} <{{.*}}:1, col:8> col:8 struct A + +struct B; +// CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:8> col:8 struct B + +struct A { + // CHECK: RecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+20]]:1> line:[[@LINE-1]]:8 struct A definition + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int' + int b, c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 b 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:3, col:10> col:10 c 'int' + int d : 12; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 + int : 0; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:3 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0 + int e : 10; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10 + struct B *f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13> col:13 f 'struct B *' +}; + +struct C { + // CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+36]]:1> line:[[@LINE-1]]:8 struct C definition + struct { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+3]]:3> line:[[@LINE-1]]:3 struct definition + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int' + } b; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (anonymous struct at {{.*}}:[[@LINE-5]]:3)':'struct C::(anonymous at {{.*}}:[[@LINE-5]]:3)' + + union { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+5]]:3> line:[[@LINE-1]]:3 union definition + int c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 c 'int' + float d; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:11> col:11 d 'float' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:3> col:3 implicit 'union C::(anonymous at {{.*}}:[[@LINE-7]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:9> col:9 implicit c 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union C::(anonymous at {{.*}}:[[@LINE-9]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:11> col:11 implicit d 'float' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union C::(anonymous at {{.*}}:[[@LINE-12]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' + + struct { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+4]]:3> line:[[@LINE-1]]:3 struct definition + int e, f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 e 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:5, col:12> col:12 f 'int' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:3> col:3 implicit 'struct C::(anonymous at {{.*}}:[[@LINE-6]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:9> col:9 implicit e 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct C::(anonymous at {{.*}}:[[@LINE-8]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <col:12> col:12 implicit f 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct C::(anonymous at {{.*}}:[[@LINE-11]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' +}; + +struct D { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+7]]:1> line:[[@LINE-1]]:8 struct D definition + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int' + int b[10]; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 b 'int [10]' + int c[]; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 c 'int []' +}; + +union E; +// CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union E + +union F; +// CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union F + +union E { + // CHECK: RecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+20]]:1> line:[[@LINE-1]]:7 union E definition + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int' + int b, c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 b 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:3, col:10> col:10 c 'int' + int d : 12; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 + int : 0; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:3 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0 + int e : 10; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10 + struct B *f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:13> col:13 f 'struct B *' +}; + +union G { + // CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+38]]:1> line:[[@LINE-1]]:7 union G definition + struct { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+3]]:3> line:[[@LINE-1]]:3 struct definition + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int' + } b; + // FIXME: note that it talks about 'struct G' below; the same happens in + // other cases with union G as well. + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:3, line:[[@LINE-3]]:5> col:5 b 'struct (anonymous struct at {{.*}}:[[@LINE-7]]:3)':'struct G::(anonymous at {{.*}}:[[@LINE-7]]:3)' + + union { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+5]]:3> line:[[@LINE-1]]:3 union definition + int c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 c 'int' + float d; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:11> col:11 d 'float' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:3> col:3 implicit 'union G::(anonymous at {{.*}}:[[@LINE-7]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:9> col:9 implicit c 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union G::(anonymous at {{.*}}:[[@LINE-9]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:11> col:11 implicit d 'float' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union G::(anonymous at {{.*}}:[[@LINE-12]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' + + struct { + // CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+4]]:3> line:[[@LINE-1]]:3 struct definition + int e, f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 e 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:5, col:12> col:12 f 'int' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:3> col:3 implicit 'struct G::(anonymous at {{.*}}:[[@LINE-6]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:9> col:9 implicit e 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct G::(anonymous at {{.*}}:[[@LINE-8]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <col:12> col:12 implicit f 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct G::(anonymous at {{.*}}:[[@LINE-11]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' +}; + diff --git a/test/AST/ast-dump-records.cpp b/test/AST/ast-dump-records.cpp new file mode 100644 index 0000000000000..e48d406bafdd6 --- /dev/null +++ b/test/AST/ast-dump-records.cpp @@ -0,0 +1,276 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump %s | FileCheck -strict-whitespace %s + +struct A; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <{{.*}}:1, col:8> col:8 struct A + +struct B; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:8> col:8 referenced struct B + +struct A { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+29]]:1> line:[[@LINE-1]]:8 struct A definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:8> col:8 implicit struct A + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int' + int b, c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 b 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:3, col:10> col:10 c 'int' + int d : 12; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 + int : 0; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0 + int e : 10; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10 + B *f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:6> col:6 f 'B *' +}; + +struct C { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+66]]:1> line:[[@LINE-1]]:8 struct C definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal has_variant_members + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:8> col:8 implicit struct C + struct { + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+10]]:3> line:[[@LINE-1]]:3 struct definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int' + } b; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-12]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (anonymous struct at {{.*}}:[[@LINE-12]]:3)':'C::(anonymous struct at {{.*}}:[[@LINE-12]]:3)' + + union { + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+12]]:3> line:[[@LINE-1]]:3 union definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + int c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 c 'int' + float d; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:11> col:11 d 'float' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-14]]:3> col:3 implicit 'C::(anonymous union at {{.*}}:[[@LINE-14]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:9> col:9 implicit c 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous union at {{.*}}:[[@LINE-16]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:11> col:11 implicit d 'float' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous union at {{.*}}:[[@LINE-19]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' + + struct { + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+11]]:3> line:[[@LINE-1]]:3 struct definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + int e, f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 e 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:5, col:12> col:12 f 'int' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-13]]:3> col:3 implicit 'C::(anonymous struct at {{.*}}:[[@LINE-13]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:9> col:9 implicit e 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous struct at {{.*}}:[[@LINE-15]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <col:12> col:12 implicit f 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous struct at {{.*}}:[[@LINE-18]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' +}; + +struct D { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+16]]:1> line:[[@LINE-1]]:8 struct D definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:8> col:8 implicit struct D + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int' + int b[10]; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 b 'int [10]' + int c[]; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 c 'int []' +}; + +union E; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union E + +union F; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union F + +union E { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+29]]:1> line:[[@LINE-1]]:7 union E definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:7> col:7 implicit union E + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 a 'int' + int b, c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:7> col:7 b 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:3, col:10> col:10 c 'int' + int d : 12; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 + int : 0; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0 + int e : 10; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int' + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10 + B *f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:6> col:6 f 'B *' +}; + +union G { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+71]]:1> line:[[@LINE-1]]:7 union G definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:1, col:7> col:7 implicit union G + struct { + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+11]]:3> line:[[@LINE-1]]:3 struct definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + int a; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int' + } b; + // FIXME: note that it talks about 'struct G' below; the same happens in + // other cases with union G as well. + // CHECK: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-15]]:3, line:[[@LINE-3]]:5> col:5 b 'struct (anonymous struct at {{.*}}:[[@LINE-15]]:3)':'G::(anonymous struct at {{.*}}:[[@LINE-15]]:3)' + + union { + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+13]]:3> line:[[@LINE-1]]:3 union definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + int c; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 c 'int' + float d; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:11> col:11 d 'float' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-15]]:3> col:3 implicit 'G::(anonymous union at {{.*}}:[[@LINE-15]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-6]]:9> col:9 implicit c 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous union at {{.*}}:[[@LINE-17]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:11> col:11 implicit d 'float' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous union at {{.*}}:[[@LINE-20]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' + + struct { + // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+12]]:3> line:[[@LINE-1]]:3 struct definition + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit + // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit + // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit + // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit + + int e, f; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 e 'int' + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:5, col:12> col:12 f 'int' + }; + // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-14]]:3> col:3 implicit 'G::(anonymous struct at {{.*}}:[[@LINE-14]]:3)' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:9> col:9 implicit e 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous struct at {{.*}}:[[@LINE-16]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' + // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} <col:12> col:12 implicit f 'int' + // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous struct at {{.*}}:[[@LINE-19]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' +}; + +struct Base1 {}; +struct Base2 {}; +struct Base3 {}; + +struct Derived1 : Base1 { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived1 definition + // CHECK: public 'Base1' +}; + +struct Derived2 : private Base1 { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived2 definition + // CHECK: private 'Base1' +}; + +struct Derived3 : virtual Base1 { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived3 definition + // CHECK: virtual public 'Base1' +}; + +struct Derived4 : Base1, virtual Base2, protected Base3 { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:1> line:[[@LINE-1]]:8 struct Derived4 definition + // CHECK: public 'Base1' + // CHECK-NEXT: virtual public 'Base2' + // CHECK-NEXT: protected 'Base3' +}; + +struct Derived5 : protected virtual Base1 { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived5 definition + // CHECK: virtual protected 'Base1' +}; + +template <typename... Bases> +struct Derived6 : virtual public Bases... { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct Derived6 definition + // CHECK: virtual public 'Bases'... +}; diff --git a/test/AST/ast-dump-special-member-functions.cpp b/test/AST/ast-dump-special-member-functions.cpp new file mode 100644 index 0000000000000..0b025397fa93b --- /dev/null +++ b/test/AST/ast-dump-special-member-functions.cpp @@ -0,0 +1,446 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump %s | FileCheck -strict-whitespace %s + +// FIXME: exists + +struct TrivialDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <{{.*}}:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct TrivialDefaultConstructor definition + // CHECK: DefaultConstructor {{.*}} trivial{{.*}} + TrivialDefaultConstructor() = default; +}; + +struct NontrivialDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NontrivialDefaultConstructor definition + // CHECK: DefaultConstructor {{.*}}non_trivial{{.*}} + NontrivialDefaultConstructor() {} +}; + +struct UserProvidedDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct UserProvidedDefaultConstructor definition + // CHECK: DefaultConstructor {{.*}}user_provided{{.*}} + UserProvidedDefaultConstructor() {} +}; + +struct NonUserProvidedDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NonUserProvidedDefaultConstructor definition + // CHECK-NOT: DefaultConstructor {{.*}}user_provided{{.*}} +}; + +struct HasConstexprDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct HasConstexprDefaultConstructor definition + // CHECK: DefaultConstructor {{.*}}constexpr{{.*}} + constexpr HasConstexprDefaultConstructor() {} +}; + +struct DoesNotHaveConstexprDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotHaveConstexprDefaultConstructor definition + // CHECK-NOT: DefaultConstructor {{.*}} constexpr{{.*}} + DoesNotHaveConstexprDefaultConstructor() {} +}; + +struct NeedsImplicitDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NeedsImplicitDefaultConstructor definition + // CHECK: DefaultConstructor {{.*}}needs_implicit{{.*}} + int i = 12; +}; + +struct DoesNotNeedImplicitDefaultConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotNeedImplicitDefaultConstructor definition + // CHECK-NOT: DefaultConstructor {{.*}}needs_implicit{{.*}} + DoesNotNeedImplicitDefaultConstructor() {} +}; + +struct DefaultedDefaultConstructorIsConstexpr { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DefaultedDefaultConstructorIsConstexpr definition + // CHECK: DefaultConstructor {{.*}}defaulted_is_constexpr{{.*}} + DefaultedDefaultConstructorIsConstexpr() = default; +}; + +struct DefaultedDefaultConstructorIsNotConstexpr { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+6]]:1> line:[[@LINE-1]]:8 struct DefaultedDefaultConstructorIsNotConstexpr definition + // CHECK-NOT: DefaultConstructor {{.*}}defaulted_is_constexpr{{.*}} + DefaultedDefaultConstructorIsNotConstexpr() = default; + union { + int i; + }; +}; + +struct SimpleCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct SimpleCopyConstructor definition + // CHECK: CopyConstructor {{.*}}simple{{.*}} + int i = 12; +}; + +struct NotSimpleCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NotSimpleCopyConstructor definition + // CHECK-NOT: CopyConstructor {{.*}}simple{{.*}} + NotSimpleCopyConstructor(const NotSimpleCopyConstructor&) = delete; +}; + +struct TrivialCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct TrivialCopyConstructor definition + // CHECK: CopyConstructor {{.*}} trivial{{.*}} + TrivialCopyConstructor() = default; +}; + +struct NontrivialCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NontrivialCopyConstructor definition + // CHECK: CopyConstructor {{.*}}non_trivial{{.*}} + NontrivialCopyConstructor(const NontrivialCopyConstructor&) {} +}; + +struct UserDeclaredCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct UserDeclaredCopyConstructor definition + // CHECK: CopyConstructor {{.*}}user_declared{{.*}} + UserDeclaredCopyConstructor(const UserDeclaredCopyConstructor&) {} +}; + +struct NonUserDeclaredCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NonUserDeclaredCopyConstructor definition + // CHECK-NOT: CopyConstructor {{.*}}user_declared{{.*}} +}; + +struct CopyConstructorHasConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyConstructorHasConstParam definition + // CHECK: CopyConstructor {{.*}}has_const_param{{.*}} + CopyConstructorHasConstParam(const CopyConstructorHasConstParam&) {} +}; + +struct CopyConstructorDoesNotHaveConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyConstructorDoesNotHaveConstParam definition + // CHECK-NOT: CopyConstructor {{.*}} has_const_param{{.*}} + CopyConstructorDoesNotHaveConstParam(CopyConstructorDoesNotHaveConstParam&) {} +}; + +struct NeedsImplicitCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NeedsImplicitCopyConstructor definition + // CHECK: CopyConstructor {{.*}}needs_implicit{{.*}} + int i = 12; +}; + +struct DoesNotNeedImplicitCopyConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotNeedImplicitCopyConstructor definition + // CHECK-NOT: CopyConstructor {{.*}}needs_implicit{{.*}} + DoesNotNeedImplicitCopyConstructor(const DoesNotNeedImplicitCopyConstructor&) {} +}; + +struct DeletedDestructor { +private: + ~DeletedDestructor() = delete; +}; + +struct CopyConstructorNeedsOverloadResolution : virtual DeletedDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct CopyConstructorNeedsOverloadResolution definition + // CHECK: CopyConstructor {{.*}}needs_overload_resolution{{.*}} +}; + +struct CopyConstructorDoesNotNeedOverloadResolution { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct CopyConstructorDoesNotNeedOverloadResolution definition + // CHECK-NOT: CopyConstructor {{.*}}needs_overload_resolution{{.*}} +}; + +struct DefaultedCopyConstructorIsDeleted { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:1> line:[[@LINE-1]]:8 struct DefaultedCopyConstructorIsDeleted definition + // CHECK: CopyConstructor {{.*}}defaulted_is_deleted{{.*}} + int &&i; + DefaultedCopyConstructorIsDeleted(const DefaultedCopyConstructorIsDeleted&) = default; +}; + +struct DefaultedCopyConstructorIsNotDeleted { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:1> line:[[@LINE-1]]:8 struct DefaultedCopyConstructorIsNotDeleted definition + // CHECK-NOT: CopyConstructor {{.*}}defaulted_is_deleted{{.*}} + int i; + DefaultedCopyConstructorIsNotDeleted(const DefaultedCopyConstructorIsNotDeleted&) = default; +}; + +struct BaseWithoutCopyConstructorConstParam { + BaseWithoutCopyConstructorConstParam(BaseWithoutCopyConstructorConstParam&); +}; + +struct ImplicitCopyConstructorHasConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct ImplicitCopyConstructorHasConstParam definition + // CHECK: CopyConstructor {{.*}}implicit_has_const_param{{.*}} +}; + +struct ImplicitCopyConstructorDoesNotHaveConstParam : BaseWithoutCopyConstructorConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct ImplicitCopyConstructorDoesNotHaveConstParam definition + // CHECK-NOT: CopyConstructor {{.*}}implicit_has_const_param{{.*}} +}; + +struct MoveConstructorExists { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct MoveConstructorExists definition + // CHECK: MoveConstructor {{.*}}exists{{.*}} +}; + +struct MoveConstructorDoesNotExist { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct MoveConstructorDoesNotExist definition + // CHECK-NOT: MoveConstructor {{.*}}exists{{.*}} + MoveConstructorDoesNotExist(const MoveConstructorDoesNotExist&); +}; + +struct SimpleMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct SimpleMoveConstructor definition + // CHECK: MoveConstructor {{.*}}simple{{.*}} + int i = 12; +}; + +struct NotSimpleMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NotSimpleMoveConstructor definition + // CHECK-NOT: MoveConstructor {{.*}}simple{{.*}} + NotSimpleMoveConstructor(NotSimpleMoveConstructor&&) = delete; +}; + +struct TrivialMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct TrivialMoveConstructor definition + // CHECK: MoveConstructor {{.*}} trivial{{.*}} + TrivialMoveConstructor() = default; +}; + +struct NontrivialMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NontrivialMoveConstructor definition + // CHECK: MoveConstructor {{.*}}non_trivial{{.*}} + NontrivialMoveConstructor(NontrivialMoveConstructor&&) {} +}; + +struct UserDeclaredMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct UserDeclaredMoveConstructor definition + // CHECK: MoveConstructor {{.*}}user_declared{{.*}} + UserDeclaredMoveConstructor(UserDeclaredMoveConstructor&&) {} +}; + +struct NonUserDeclaredMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NonUserDeclaredMoveConstructor definition + // CHECK-NOT: MoveConstructor {{.*}}user_declared{{.*}} +}; + +struct NeedsImplicitMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NeedsImplicitMoveConstructor definition + // CHECK: MoveConstructor {{.*}}needs_implicit{{.*}} + int i = 12; +}; + +struct DoesNotNeedImplicitMoveConstructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotNeedImplicitMoveConstructor definition + // CHECK-NOT: MoveConstructor {{.*}}needs_implicit{{.*}} + DoesNotNeedImplicitMoveConstructor(DoesNotNeedImplicitMoveConstructor&&) {} +}; + +struct MoveConstructorNeedsOverloadResolution : virtual DeletedDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct MoveConstructorNeedsOverloadResolution definition + // CHECK: MoveConstructor {{.*}}needs_overload_resolution{{.*}} +}; + +struct MoveConstructorDoesNotNeedOverloadResolution { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct MoveConstructorDoesNotNeedOverloadResolution definition + // CHECK-NOT: MoveConstructor {{.*}}needs_overload_resolution{{.*}} +}; + +// FIXME: defaulted_is_deleted + +struct TrivialCopyAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct TrivialCopyAssignment definition + // CHECK: CopyAssignment {{.*}} trivial{{.*}} + TrivialCopyAssignment& operator=(const TrivialCopyAssignment&) = default; +}; + +struct NontrivialCopyAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NontrivialCopyAssignment definition + // CHECK: CopyAssignment {{.*}}non_trivial{{.*}} + NontrivialCopyAssignment& operator=(const NontrivialCopyAssignment&) {} +}; + +struct CopyAssignmentHasConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyAssignmentHasConstParam definition + // CHECK: CopyAssignment {{.*}}has_const_param{{.*}} + CopyAssignmentHasConstParam& operator=(const CopyAssignmentHasConstParam&) {} +}; + +struct CopyAssignmentDoesNotHaveConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyAssignmentDoesNotHaveConstParam definition + // CHECK-NOT: CopyAssignment {{.*}} has_const_param{{.*}} + CopyAssignmentDoesNotHaveConstParam& operator=(CopyAssignmentDoesNotHaveConstParam&) {} +}; + +struct UserDeclaredCopyAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct UserDeclaredCopyAssignment definition + // CHECK: CopyAssignment {{.*}}user_declared{{.*}} + UserDeclaredCopyAssignment& operator=(const UserDeclaredCopyAssignment&) {} +}; + +struct NonUserDeclaredCopyAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NonUserDeclaredCopyAssignment definition + // CHECK-NOT: CopyAssignment {{.*}}user_declared{{.*}} +}; + +struct NeedsImplicitCopyAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NeedsImplicitCopyAssignment definition + // CHECK: CopyAssignment {{.*}}needs_implicit{{.*}} + int i = 12; +}; + +struct DoesNotNeedImplicitCopyAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotNeedImplicitCopyAssignment definition + // CHECK-NOT: CopyAssignment {{.*}}needs_implicit{{.*}} + DoesNotNeedImplicitCopyAssignment& operator=(const DoesNotNeedImplicitCopyAssignment&) {} +}; + +struct CopyAssignmentNeedsOverloadResolution { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyAssignmentNeedsOverloadResolution definition + // CHECK: CopyAssignment {{.*}}needs_overload_resolution{{.*}} + mutable int i; +}; + +struct CopyAssignmentDoesNotNeedOverloadResolution { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct CopyAssignmentDoesNotNeedOverloadResolution definition + // CHECK-NOT: CopyAssignment {{.*}}needs_overload_resolution{{.*}} +}; + +struct BaseWithoutCopyAssignmentConstParam { + BaseWithoutCopyAssignmentConstParam& operator=(BaseWithoutCopyAssignmentConstParam&); +}; + +struct ImplicitCopyAssignmentHasConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct ImplicitCopyAssignmentHasConstParam definition + // CHECK: CopyAssignment {{.*}}implicit_has_const_param{{.*}} +}; + +struct ImplicitCopyAssignmentDoesNotHaveConstParam : BaseWithoutCopyAssignmentConstParam { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct ImplicitCopyAssignmentDoesNotHaveConstParam definition + // CHECK-NOT: CopyAssignment {{.*}}implicit_has_const_param{{.*}} +}; + +struct MoveAssignmentExists { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct MoveAssignmentExists definition + // CHECK: MoveAssignment {{.*}}exists{{.*}} +}; + +struct MoveAssignmentDoesNotExist { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct MoveAssignmentDoesNotExist definition + // CHECK-NOT: MoveAssignment {{.*}}exists{{.*}} + MoveAssignmentDoesNotExist& operator=(const MoveAssignmentDoesNotExist&); +}; + +struct SimpleMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct SimpleMoveAssignment definition + // CHECK: MoveAssignment {{.*}}simple{{.*}} + int i = 12; +}; + +struct NotSimpleMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NotSimpleMoveAssignment definition + // CHECK-NOT: MoveAssignment {{.*}}simple{{.*}} + NotSimpleMoveAssignment& operator=(NotSimpleMoveAssignment&&) = delete; +}; + +struct TrivialMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct TrivialMoveAssignment definition + // CHECK: MoveAssignment {{.*}} trivial{{.*}} + TrivialMoveAssignment() = default; +}; + +struct NontrivialMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NontrivialMoveAssignment definition + // CHECK: MoveAssignment {{.*}}non_trivial{{.*}} + NontrivialMoveAssignment& operator=(NontrivialMoveAssignment&&) {} +}; + +struct UserDeclaredMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct UserDeclaredMoveAssignment definition + // CHECK: MoveAssignment {{.*}}user_declared{{.*}} + UserDeclaredMoveAssignment& operator=(UserDeclaredMoveAssignment&&) {} +}; + +struct NonUserDeclaredMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NonUserDeclaredMoveAssignment definition + // CHECK-NOT: MoveAssignment {{.*}}user_declared{{.*}} +}; + +struct NeedsImplicitMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NeedsImplicitMoveAssignment definition + // CHECK: MoveAssignment {{.*}}needs_implicit{{.*}} + int i = 12; +}; + +struct DoesNotNeedImplicitMoveAssignment { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotNeedImplicitMoveAssignment definition + // CHECK-NOT: MoveAssignment {{.*}}needs_implicit{{.*}} + DoesNotNeedImplicitMoveAssignment& operator=(DoesNotNeedImplicitMoveAssignment&&) {} +}; + +struct MoveAssignmentNeedsOverloadResolution : virtual DeletedDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct MoveAssignmentNeedsOverloadResolution definition + // CHECK: MoveAssignment {{.*}}needs_overload_resolution{{.*}} +}; + +struct MoveAssignmentDoesNotNeedOverloadResolution { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct MoveAssignmentDoesNotNeedOverloadResolution definition + // CHECK-NOT: MoveAssignment {{.*}}needs_overload_resolution{{.*}} +}; + +struct SimpleDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct SimpleDestructor definition + // CHECK: Destructor {{.*}}simple{{.*}} +}; + +struct NotSimpleDestructor : DeletedDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NotSimpleDestructor definition + // CHECK-NOT: Destructor {{.*}}simple{{.*}} +}; + +struct IrrelevantDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct IrrelevantDestructor definition + // CHECK: Destructor {{.*}}irrelevant{{.*}} +}; + +struct RelevantDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct RelevantDestructor definition + // CHECK-NOT: Destructor {{.*}}irrelevant{{.*}} + ~RelevantDestructor() {} +}; + +struct TrivialDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct TrivialDestructor definition + // CHECK: Destructor {{.*}} trivial{{.*}} + ~TrivialDestructor() = default; +}; + +struct NontrivialDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NontrivialDestructor definition + // CHECK: Destructor {{.*}}non_trivial{{.*}} + ~NontrivialDestructor() {} +}; + +struct UserDeclaredDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct UserDeclaredDestructor definition + // CHECK: Destructor {{.*}}user_declared{{.*}} + ~UserDeclaredDestructor() {} +}; + +struct NonUserDeclaredDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct NonUserDeclaredDestructor definition + // CHECK-NOT: Destructor {{.*}}user_declared{{.*}} +}; + +struct NeedsImplicitDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct NeedsImplicitDestructor definition + // CHECK: Destructor {{.*}}needs_implicit{{.*}} + int i = 12; +}; + +struct DoesNotNeedImplicitDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DoesNotNeedImplicitDestructor definition + // CHECK-NOT: Destructor {{.*}}needs_implicit{{.*}} + ~DoesNotNeedImplicitDestructor() {} +}; + +struct DestructorNeedsOverloadResolution : virtual DeletedDestructor { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct DestructorNeedsOverloadResolution definition + // CHECK: Destructor {{.*}}needs_overload_resolution{{.*}} + ~DestructorNeedsOverloadResolution(); +}; + +struct DestructorDoesNotNeedOverloadResolution { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct DestructorDoesNotNeedOverloadResolution definition + // CHECK-NOT: Destructor {{.*}}needs_overload_resolution{{.*}} +}; + +// FIXME: defaulted_is_deleted diff --git a/test/AST/ast-dump-stmt.c b/test/AST/ast-dump-stmt.c new file mode 100644 index 0000000000000..8fec31d95a0e7 --- /dev/null +++ b/test/AST/ast-dump-stmt.c @@ -0,0 +1,375 @@ +// RUN: %clang_cc1 -std=gnu11 -ast-dump %s | FileCheck -strict-whitespace %s + +int TestLocation = 0; +// CHECK: VarDecl{{.*}}TestLocation +// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:20> 'int' 0 + +int TestIndent = 1 + (1); +// CHECK: VarDecl{{.*}}TestIndent +// CHECK-NEXT: {{^}}| `-BinaryOperator{{[^()]*$}} +// CHECK-NEXT: {{^}}| |-IntegerLiteral{{.*0[^()]*$}} +// CHECK-NEXT: {{^}}| `-ParenExpr{{.*0[^()]*$}} +// CHECK-NEXT: {{^}}| `-IntegerLiteral{{.*0[^()]*$}} + +void TestDeclStmt() { + int x = 0; + int y, z; +} +// CHECK: FunctionDecl{{.*}}TestDeclStmt +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl{{.*}}x +// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl{{.*}}y +// CHECK-NEXT: VarDecl{{.*}}z + +int TestOpaqueValueExpr = 0 ?: 1; +// CHECK: VarDecl{{.*}}TestOpaqueValueExpr +// CHECK-NEXT: BinaryConditionalOperator +// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: OpaqueValueExpr +// CHECK-NEXT: IntegerLiteral +// CHECK-NEXT: OpaqueValueExpr
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+
+void TestUnaryOperatorExpr(void) {
+ char T1 = 1;
+ int T2 = 1;
+
+ T1++;
+ T2++;
+ // CHECK: UnaryOperator{{.*}}postfix '++' cannot overflow
+ // CHECK-NEXT: DeclRefExpr{{.*}}'T1' 'char'
+ // CHECK-NOT: UnaryOperator{{.*}}postfix '++' cannot overflow
+ // CHECK: DeclRefExpr{{.*}}'T2' 'int'
+
+ -T1;
+ -T2;
+ // CHECK: UnaryOperator{{.*}}prefix '-' cannot overflow
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'T1' 'char'
+ // CHECK-NOT: UnaryOperator{{.*}}prefix '-' cannot overflow
+ // CHECK: ImplicitCastExpr
+ // CHECK: DeclRefExpr{{.*}}'T2' 'int'
+
+ ~T1;
+ ~T2;
+ // CHECK: UnaryOperator{{.*}}prefix '~' cannot overflow
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'T1' 'char'
+ // CHECK: UnaryOperator{{.*}}prefix '~' cannot overflow
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'T2' 'int'
+}
+
+void TestGenericSelectionExpressions(int i) {
+ _Generic(i, int : 12);
+ // CHECK: GenericSelectionExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:23> 'int'
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}}
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // FIXME: note that the following test line has a spurious whitespace.
+ // CHECK-NEXT: case 'int' selected
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:21> 'int' 12
+ _Generic(i, int : 12, default : 0);
+ // CHECK: GenericSelectionExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:36> 'int'
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}}
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // FIXME: note that the following test line has a spurious whitespace.
+ // CHECK-NEXT: case 'int' selected
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:21> 'int' 12
+ // CHECK-NEXT: default
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:35> 'int' 0
+ _Generic(i, default : 0, int : 12);
+ // CHECK: GenericSelectionExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:36> 'int'
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}}
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // CHECK-NEXT: default
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:25> 'int' 0
+ // FIXME: note that the following test line has a spurious whitespace.
+ // CHECK-NEXT: case 'int' selected
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:34> 'int' 12
+ _Generic(i, int : 12, float : 10, default : 100);
+ // CHECK: GenericSelectionExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:50> 'int'
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}}
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // FIXME: note that the following test line has a spurious whitespace.
+ // CHECK-NEXT: case 'int' selected
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:21> 'int' 12
+ // FIXME: note that the following test line has a spurious whitespace.
+ // CHECK-NEXT: case 'float'
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'float'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:33> 'int' 10
+ // CHECK-NEXT: default
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:47> 'int' 100
+
+ int j = _Generic(i, int : 12);
+ // CHECK: DeclStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:32>
+ // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:3, col:31> col:7 j 'int' cinit
+ // CHECK-NEXT: GenericSelectionExpr 0x{{[^ ]*}} <col:11, col:31> 'int'
+ // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}}
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:20> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // FIXME: note that the following test line has a spurious whitespace.
+ // CHECK-NEXT: case 'int' selected
+ // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:29> 'int' 12
+}
+
+void TestLabelsAndGoto(void) {
+ // Note: case and default labels are handled by TestSwitch().
+
+label1:
+ ;
+ // CHECK: LabelStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:3> 'label1'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <col:3>
+
+ goto label2;
+ // CHECK-NEXT: GotoStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:8> 'label2' 0x{{[^ ]*}}
+
+label2:
+ 0;
+ // CHECK-NEXT: LabelStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:3> 'label2'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:3> 'int' 0
+
+ void *ptr = &&label1;
+ // CHECK-NEXT: DeclStmt
+ // CHECK-NEXT: VarDecl
+ // CHECK-NEXT: AddrLabelExpr 0x{{[^ ]*}} <col:15, col:17> 'void *' label1 0x{{[^ ]*}}
+
+ goto *ptr;
+ // CHECK-NEXT: IndirectGotoStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:9> 'void *' lvalue Var 0x{{[^ ]*}} 'ptr' 'void *'
+}
+
+void TestSwitch(int i) {
+ switch (i) {
+ // CHECK: SwitchStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+32]]:3>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:11> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:14, line:[[@LINE+29]]:3>
+ case 0:
+ break;
+ // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: ConstantExpr
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 0
+ // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:5>
+ case 1:
+ case 2:
+ break;
+ // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-3]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: ConstantExpr
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 1
+ // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-5]]:3, line:[[@LINE-4]]:5>
+ // CHECK-NEXT: ConstantExpr
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 2
+ // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-7]]:5>
+ default:
+ break;
+ // CHECK-NEXT: DefaultStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <col:5>
+ case 3 ... 5:
+ break;
+ // CHECK-NEXT: CaseStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> gnu_range
+ // CHECK-NEXT: ConstantExpr
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:8> 'int' 3
+ // CHECK-NEXT: ConstantExpr
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:14> 'int' 5
+ // CHECK-NEXT: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-6]]:5>
+ }
+}
+
+void TestIf(_Bool b) {
+ if (b)
+ ;
+ // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt
+
+ if (b) {}
+ // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: CompoundStmt
+
+ if (b)
+ ;
+ else
+ ;
+ // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:3, line:[[@LINE-1]]:5> has_else
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-6]]:5>
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-5]]:5>
+
+ if (b) {}
+ else {}
+ // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:9> has_else
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:10, col:11>
+ // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <line:[[@LINE-5]]:8, col:9>
+
+ if (b)
+ ;
+ else if (b)
+ ;
+ // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:3, line:[[@LINE-1]]:5> has_else
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-6]]:5>
+ // CHECK-NEXT: IfStmt 0x{{[^ ]*}} <line:[[@LINE-6]]:8, line:[[@LINE-5]]:5>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-8]]:5>
+
+ if (b)
+ ;
+ else if (b)
+ ;
+ else
+ ;
+ // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-6]]:3, line:[[@LINE-1]]:5> has_else
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:7> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-8]]:5>
+ // CHECK-NEXT: IfStmt 0x{{[^ ]*}} <line:[[@LINE-8]]:8, line:[[@LINE-5]]:5> has_else
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-10]]:5>
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-9]]:5>
+}
+
+void TestIteration(_Bool b) {
+ while (b)
+ ;
+ // CHECK: WhileStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:5>
+
+ do
+ ;
+ while (b);
+ // CHECK: DoStmt 0x{{[^ ]*}} <line:[[@LINE-3]]:3, line:[[@LINE-1]]:11>
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <line:[[@LINE-3]]:5>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+
+ for (int i = 0; i < 10; ++i)
+ ;
+ // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: DeclStmt
+ // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:8, col:16> col:12 used i 'int' cinit
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:16> 'int' 0
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:19, col:23> 'int' '<'
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:19> 'int' lvalue Var 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:23> 'int' 10
+ // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:27, col:29> 'int' prefix '++'
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:29> 'int' lvalue Var 0x{{[^ ]*}} 'i' 'int'
+ // CHECK-NEXT: NullStmt
+
+ for (b; b; b)
+ ;
+ // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:8> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:11> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt
+
+ for (; b; b = !b)
+ ;
+ // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:13, col:18> '_Bool' '='
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:13> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:17, col:18> 'int' prefix '!' cannot overflow
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:18> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt
+
+ for (; b;)
+ ;
+ // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:10> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: NullStmt
+
+ for (;; b = !b)
+ ;
+ // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <line:[[@LINE-6]]:11, col:16> '_Bool' '='
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:11> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:15, col:16> 'int' prefix '!' cannot overflow
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> '_Bool' lvalue ParmVar 0x{{[^ ]*}} 'b' '_Bool'
+ // CHECK-NEXT: NullStmt
+
+ for (;;)
+ ;
+ // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: <<<NULL>>>
+ // CHECK-NEXT: NullStmt
+}
+
+void TestJumps(void) {
+ // goto and computed goto was tested in TestLabelsAndGoto().
+
+ while (1) {
+ continue;
+ // CHECK: ContinueStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:5>
+ break;
+ // CHECK: BreakStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:5>
+ }
+ return;
+ // CHECK: ReturnStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3>
+
+ return TestSwitch(1);
+ // CHECK: ReturnStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:22>
+ // CHECK-NEXT: CallExpr 0x{{[^ ]*}} <col:10, col:22> 'void'
+}
+
+void TestMiscStmts(void) {
+ ({int a = 10; a;});
+ // CHECK: StmtExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:20> 'int'
+ // CHECK-NEXT: CompoundStmt
+ // CHECK-NEXT: DeclStmt
+ // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:5, col:13> col:9 used a 'int' cinit
+ // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:13> 'int' 10
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:17> 'int' lvalue Var 0x{{[^ ]*}} 'a' 'int'
+}
diff --git a/test/AST/ast-dump-stmt.cpp b/test/AST/ast-dump-stmt.cpp new file mode 100644 index 0000000000000..9df4ee26cd9a0 --- /dev/null +++ b/test/AST/ast-dump-stmt.cpp @@ -0,0 +1,272 @@ +// RUN: %clang_cc1 -std=c++2a -triple x86_64-linux-gnu -fcxx-exceptions -ast-dump %s | FileCheck -strict-whitespace %s + +namespace n { +void function() {} +int Variable; +} +using n::function; +using n::Variable; +void TestFunction() { + void (*f)() = &function; +// CHECK: DeclRefExpr{{.*}} (UsingShadow{{.*}}function + Variable = 4; +// CHECK: DeclRefExpr{{.*}} (UsingShadow{{.*}}Variable +} + +// CHECK: FunctionDecl {{.*}} TestCatch1 +void TestCatch1() { +// CHECK: CXXTryStmt +// CHECK-NEXT: CompoundStmt + try { + } +// CHECK-NEXT: CXXCatchStmt +// CHECK-NEXT: VarDecl {{.*}} x +// CHECK-NEXT: CompoundStmt + catch (int x) { + } +} + +// CHECK: FunctionDecl {{.*}} TestCatch2 +void TestCatch2() { +// CHECK: CXXTryStmt +// CHECK-NEXT: CompoundStmt + try { + } +// CHECK-NEXT: CXXCatchStmt +// CHECK-NEXT: NULL +// CHECK-NEXT: CompoundStmt + catch (...) { + } +} + +void TestAllocationExprs() { + int *p; + p = new int; + delete p; + p = new int[2]; + delete[] p; + p = ::new int; + ::delete p; +} +// CHECK: FunctionDecl {{.*}} TestAllocationExprs +// CHECK: CXXNewExpr {{.*}} 'int *' Function {{.*}} 'operator new' +// CHECK: CXXDeleteExpr {{.*}} 'void' Function {{.*}} 'operator delete' +// CHECK: CXXNewExpr {{.*}} 'int *' array Function {{.*}} 'operator new[]' +// CHECK: CXXDeleteExpr {{.*}} 'void' array Function {{.*}} 'operator delete[]' +// CHECK: CXXNewExpr {{.*}} 'int *' global Function {{.*}} 'operator new' +// CHECK: CXXDeleteExpr {{.*}} 'void' global Function {{.*}} 'operator delete' + +// Don't crash on dependent exprs that haven't been resolved yet. +template <typename T> +void TestDependentAllocationExpr() { + T *p = new T; + delete p; +} +// CHECK: FunctionTemplateDecl {{.*}} TestDependentAllocationExpr +// CHECK: CXXNewExpr {{.*'T \*'$}} +// CHECK: CXXDeleteExpr {{.*'void'$}} + +template <typename T> +class DependentScopeMemberExprWrapper { + T member; +}; + +template <typename T> +void TestDependentScopeMemberExpr() { + DependentScopeMemberExprWrapper<T> obj; + obj.member = T(); + (&obj)->member = T(); +} +// CHECK: FunctionTemplateDecl {{.*}} TestDependentScopeMemberExpr +// CHECK: CXXDependentScopeMemberExpr {{.*}} lvalue .member +// CHECK: CXXDependentScopeMemberExpr {{.*}} lvalue ->member + +union U { + int i; + long l; +}; + +void TestUnionInitList() +{ + U us[3] = {1}; +// CHECK: VarDecl {{.+}} <col:3, col:15> col:5 us 'U [3]' cinit +// CHECK-NEXT: `-InitListExpr {{.+}} <col:13, col:15> 'U [3]' +// CHECK-NEXT: |-array_filler: InitListExpr {{.+}} <col:15> 'U' field Field {{.+}} 'i' 'int' +// CHECK-NEXT: `-InitListExpr {{.+}} <col:14> 'U' field Field {{.+}} 'i' 'int' +// CHECK-NEXT: `-IntegerLiteral {{.+}} <col:14> 'int' 1 +} + +void TestSwitch(int i) { + switch (int a; i) + ; + // CHECK: SwitchStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> has_init + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:11, col:15> col:15 a 'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:18> 'int' lvalue ParmVar 0x{{[^ ]*}} 'i' 'int' + // CHECK-NEXT: NullStmt +} + +void TestIf(bool b) { + if (int i = 12; b) + ; + // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> has_init + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:7, col:15> col:11 i 'int' cinit + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:15> 'int' 12 + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:19> 'bool' lvalue ParmVar 0x{{[^ ]*}} 'b' 'bool' + // CHECK-NEXT: NullStmt + + if constexpr (sizeof(b) == 1) + ; + // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <line:[[@LINE-3]]:17, col:30> 'bool' + // CHECK-NEXT: BinaryOperator + // CHECK-NEXT: UnaryExprOrTypeTraitExpr + // CHECK-NEXT: ParenExpr + // CHECK-NEXT: DeclRefExpr + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: IntegerLiteral + // CHECK-NEXT: NullStmt + + if constexpr (sizeof(b) == 1) + ; + else + ; + // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:3, line:[[@LINE-1]]:5> has_else + // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <line:[[@LINE-5]]:17, col:30> 'bool' + // CHECK-NEXT: BinaryOperator + // CHECK-NEXT: UnaryExprOrTypeTraitExpr + // CHECK-NEXT: ParenExpr + // CHECK-NEXT: DeclRefExpr + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: IntegerLiteral + // CHECK-NEXT: NullStmt + // CHECK-NEXT: NullStmt +} + +struct Container { + int *begin() const; + int *end() const; +}; + +void TestIteration() { + for (int i = 0; int j = i; ++i) + ; + // CHECK: ForStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:8, col:16> col:12 used i 'int' cinit + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:16> 'int' 0 + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:19, col:27> col:23 used j 'int' cinit + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:27> 'int' lvalue Var 0x{{[^ ]*}} 'i' 'int' + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:23> 'bool' <IntegralToBoolean> + // CHECK-NEXT: ImplicitCastExpr 0x{{[^ ]*}} <col:23> 'int' <LValueToRValue> + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:23> 'int' lvalue Var 0x{{[^ ]*}} 'j' 'int' + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:30, col:32> 'int' lvalue prefix '++' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:32> 'int' lvalue Var 0x{{[^ ]*}} 'i' 'int' + // CHECK-NEXT: NullStmt + + int vals[10]; + for (int v : vals) + ; + // CHECK: CXXForRangeStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> + // CHECK-NEXT: <<<NULL>>> + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:16> col:16 implicit used __range1 'int (&)[10]' cinit + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'int [10]' lvalue Var 0x{{[^ ]*}} 'vals' 'int [10]' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:14> col:14 implicit used __begin1 'int *':'int *' cinit + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int [10]' lvalue Var 0x{{[^ ]*}} '__range1' 'int (&)[10]' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:14, col:16> col:14 implicit used __end1 'int *':'int *' cinit + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:14, col:16> 'int *' '+' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int [10]' lvalue Var 0x{{[^ ]*}} '__range1' 'int (&)[10]' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:16> 'long' 10 + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:14> 'bool' '!=' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__end1' 'int *':'int *' + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue prefix '++' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:8, col:14> col:12 v 'int' cinit + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:14> 'int' lvalue prefix '*' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: NullStmt + + Container C; + for (int v : C) + ; + // CHECK: CXXForRangeStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> + // CHECK-NEXT: <<<NULL>>> + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:16> col:16 implicit used __range1 'Container &' cinit + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:16> 'Container' lvalue Var 0x{{[^ ]*}} 'C' 'Container' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:14> col:14 implicit used __begin1 'int *':'int *' cinit + // CHECK-NEXT: CXXMemberCallExpr 0x{{[^ ]*}} <col:14> 'int *' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:14> '<bound member function type>' .begin 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'Container' lvalue Var 0x{{[^ ]*}} '__range1' 'Container &' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:14> col:14 implicit used __end1 'int *':'int *' cinit + // CHECK-NEXT: CXXMemberCallExpr 0x{{[^ ]*}} <col:14> 'int *' + // CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:14> '<bound member function type>' .end 0x{{[^ ]*}} + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'Container' lvalue Var 0x{{[^ ]*}} '__range1' 'Container &' + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:14> 'bool' '!=' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__end1' 'int *':'int *' + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue prefix '++' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:8, col:14> col:12 v 'int' cinit + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:14> 'int' lvalue prefix '*' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:14> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: NullStmt + + for (int a; int v : vals) + ; + // CHECK: CXXForRangeStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:8, col:12> col:12 a 'int' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:23> col:23 implicit used __range1 'int (&)[10]' cinit + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:23> 'int [10]' lvalue Var 0x{{[^ ]*}} 'vals' 'int [10]' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:21> col:21 implicit used __begin1 'int *':'int *' cinit + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:21> 'int [10]' lvalue Var 0x{{[^ ]*}} '__range1' 'int (&)[10]' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:21, col:23> col:21 implicit used __end1 'int *':'int *' cinit + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:21, col:23> 'int *' '+' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:21> 'int [10]' lvalue Var 0x{{[^ ]*}} '__range1' 'int (&)[10]' + // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:23> 'long' 10 + // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:21> 'bool' '!=' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:21> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:21> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__end1' 'int *':'int *' + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:21> 'int *':'int *' lvalue prefix '++' + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:21> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl 0x{{[^ ]*}} <col:15, col:21> col:19 v 'int' cinit + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:21> 'int' lvalue prefix '*' cannot overflow + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:21> 'int *':'int *' lvalue Var 0x{{[^ ]*}} '__begin1' 'int *':'int *' + // CHECK-NEXT: NullStmt +} diff --git a/test/AST/ast-dump-stmt.m b/test/AST/ast-dump-stmt.m new file mode 100644 index 0000000000000..8c0ca897e5114 --- /dev/null +++ b/test/AST/ast-dump-stmt.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -Wno-unused -fblocks -fobjc-exceptions -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +void TestBlockExpr(int x) { + ^{ x; }; +} +// CHECK: FunctionDecl{{.*}}TestBlockExpr +// CHECK: BlockExpr{{.*}} 'void (^)(void)' +// CHECK-NEXT: BlockDecl + +void TestExprWithCleanup(int x) { + ^{ x; }; +} +// CHECK: FunctionDecl{{.*}}TestExprWithCleanup +// CHECK: ExprWithCleanups +// CHECK-NEXT: cleanup Block +// CHECK-NEXT: BlockExpr + +@interface A +@end + +void TestObjCAtCatchStmt() { + @try { + } @catch(A *a) { + } @catch(...) { + } @finally { + } +} +// CHECK: FunctionDecl{{.*}}TestObjCAtCatchStmt +// CHECK: ObjCAtTryStmt +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: ObjCAtCatchStmt{{.*}} +// CHECK-NEXT: VarDecl{{.*}}a +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: ObjCAtCatchStmt{{.*}} catch all +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: ObjCAtFinallyStmt diff --git a/test/AST/ast-dump-template-decls.cpp b/test/AST/ast-dump-template-decls.cpp new file mode 100644 index 0000000000000..a1f355b4da0d8 --- /dev/null +++ b/test/AST/ast-dump-template-decls.cpp @@ -0,0 +1,102 @@ +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -strict-whitespace %s + +template <typename Ty> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <{{.*}}:1, line:[[@LINE+2]]:10> col:6 a +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty +void a(Ty); + +template <typename... Ty> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:13> col:6 b +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:23> col:23 referenced typename depth 0 index 0 ... Ty +void b(Ty...); + +template <typename Ty, typename Uy> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:14> col:6 c +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:24, col:33> col:33 referenced typename depth 0 index 1 Uy +void c(Ty, Uy); + +template <> +void c<float, int>(float, int); +// CHECK: FunctionDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:30> col:6 c 'void (float, int)' +// CHECK: TemplateArgument type 'float' +// CHECK: TemplateArgument type 'int' + +template <typename Ty, template<typename> typename Uy> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:18> col:6 d +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty +// CHECK-NEXT: TemplateTemplateParmDecl 0x{{[^ ]*}} <col:24, col:52> col:52 depth 0 index 1 Uy +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:33> col:33 typename depth 1 index 0 +void d(Ty, Uy<Ty>); + +template <class Ty> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:10> col:6 e +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:17> col:17 referenced class depth 0 index 0 Ty +void e(Ty); + +template <int N> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:17> col:6 f +// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:15> col:15 referenced 'int' depth 0 index 0 N +void f(int i = N); + +template <typename Ty = int> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:10> col:6 g +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:25> col:20 referenced typename depth 0 index 0 Ty +// CHECK-NEXT: TemplateArgument type 'int' +void g(Ty); + +template <typename = void> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:8> col:6 h +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:22> col:11 typename depth 0 index 0 +// CHECK-NEXT: TemplateArgument type 'void' +void h(); + +template <typename Ty> +// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:11> col:8 R +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty +// CHECK: ClassTemplateSpecialization 0x{{[^ ]*}} 'R' +struct R {}; + +template <> +// CHECK: ClassTemplateSpecializationDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:16> col:8 struct R definition +// CHECK: TemplateArgument type 'int' +struct R<int> {}; + +template <typename Ty, class Uy> +// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:11> col:8 S +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:24, col:30> col:30 class depth 0 index 1 Uy +struct S {}; + +template <typename Ty> +// CHECK: ClassTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:20> col:8 struct S definition +// CHECK: TemplateArgument type 'type-parameter-0-0' +// CHECK-NEXT: TemplateArgument type 'int' +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-4]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty +struct S<Ty, int> {}; + +template <auto> +// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 T +// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11> col:15 'auto' depth 0 index 0 +struct T {}; + +template <decltype(auto)> +// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:11> col:8 U +// CHECK-NEXT: NonTypeTemplateParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11> col:25 'decltype(auto)' depth 0 index 0 +struct U {}; + +template <typename Ty> +// CHECK: ClassTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+7]]:1> line:[[@LINE+2]]:8 V +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 0 index 0 Ty +struct V { + template <typename Uy> + // CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+2]]:10> col:8 f + // CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:13, col:22> col:22 typename depth 1 index 0 Uy + void f(); +}; + +template <typename Ty> +template <typename Uy> +// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} parent 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:18> col:13 f +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 typename depth 1 index 0 Uy +void V<Ty>::f() {} diff --git a/test/AST/ast-dump-templates.cpp b/test/AST/ast-dump-templates.cpp new file mode 100644 index 0000000000000..89feee75268a3 --- /dev/null +++ b/test/AST/ast-dump-templates.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -std=c++1z -ast-print %s > %t +// RUN: FileCheck < %t %s -check-prefix=CHECK1 +// RUN: FileCheck < %t %s -check-prefix=CHECK2 +// RUN: %clang_cc1 -std=c++1z -ast-dump %s | FileCheck --check-prefix=DUMP %s + +template <int X, typename Y, int Z = 5> +struct foo { + int constant; + foo() {} + Y getSum() { return Y(X + Z); } +}; + +template <int A, typename B> +B bar() { + return B(A); +} + +void baz() { + int x = bar<5, int>(); + int y = foo<5, int>().getSum(); + double z = foo<2, double, 3>().getSum(); +} + +// Template definition - foo +// CHECK1: template <int X, typename Y, int Z = 5> struct foo { +// CHECK2: template <int X, typename Y, int Z = 5> struct foo { + +// Template instantiation - foo +// Since the order of instantiation may vary during runs, run FileCheck twice +// to make sure each instantiation is in the correct spot. +// CHECK1: template<> struct foo<5, int, 5> { +// CHECK2: template<> struct foo<2, double, 3> { + +// Template definition - bar +// CHECK1: template <int A, typename B> B bar() +// CHECK2: template <int A, typename B> B bar() + +// Template instantiation - bar +// CHECK1: template<> int bar<5, int>() +// CHECK2: template<> int bar<5, int>() + +// CHECK1-LABEL: template <typename ...T> struct A { +// CHECK1-NEXT: template <T ...x[3]> struct B { +template <typename ...T> struct A { + template <T ...x[3]> struct B {}; +}; + +// CHECK1-LABEL: template <typename ...T> void f(T ...[3]) { +// CHECK1-NEXT: A<T [3]...> a; +template <typename ...T> void f(T ...[3]) { + A<T [3]...> a; +} + +namespace test2 { +void func(int); +void func(float); +template<typename T> +void tmpl() { + func(T()); +} + +// DUMP: UnresolvedLookupExpr {{.*}} <col:3> '<overloaded function type>' lvalue (ADL) = 'func' +} + +namespace test3 { + template<typename T> struct A {}; + template<typename T> A(T) -> A<int>; + // CHECK1: template <typename T> A(T) -> A<int>; +} diff --git a/test/AST/ast-dump-wchar.cpp b/test/AST/ast-dump-wchar.cpp new file mode 100644 index 0000000000000..339295c133d14 --- /dev/null +++ b/test/AST/ast-dump-wchar.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++11 -ast-dump %s -triple x86_64-linux-gnu | FileCheck %s + +char c8[] = u8"test\0\\\"\a\b\f\n\r\t\v\234"; +// CHECK: StringLiteral {{.*}} lvalue u8"test\000\\\"\a\b\f\n\r\t\v\234" + +char16_t c16[] = u"test\0\\\"\t\a\b\234\u1234"; +// CHECK: StringLiteral {{.*}} lvalue u"test\000\\\"\t\a\b\234\u1234" + +char32_t c32[] = U"test\0\\\"\t\a\b\234\u1234\U0010ffff"; // \ +// CHECK: StringLiteral {{.*}} lvalue U"test\000\\\"\t\a\b\234\u1234\U0010FFFF" + +wchar_t wc[] = L"test\0\\\"\t\a\b\234\u1234\xffffffff"; // \ +// CHECK: StringLiteral {{.*}} lvalue L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF" diff --git a/test/AST/ast-print-attr.c b/test/AST/ast-print-attr.c new file mode 100644 index 0000000000000..223e27b397908 --- /dev/null +++ b/test/AST/ast-print-attr.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -ast-print -x objective-c++ -fms-extensions %s -o - | FileCheck %s + +// CHECK: using A = __kindof id (*)[1]; +using A = __kindof id (*)[1]; + +// CHECK: using B = int ** __ptr32 *[3]; +using B = int ** __ptr32 *[3]; + +// FIXME: This is the wrong spelling for the attribute. +// FIXME: Too many parens here! +// CHECK: using C = int ((*))() __attribute__((cdecl)); +using C = int (*)() [[gnu::cdecl]]; diff --git a/test/AST/ast-print-bool.c b/test/AST/ast-print-bool.c new file mode 100644 index 0000000000000..05519bcd4e540 --- /dev/null +++ b/test/AST/ast-print-bool.c @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_CBOOL \ +// RUN: | FileCheck %s --check-prefixes=BOOL-AS-CBOOL,CBOOL +// +// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_CBOOL -DDIAG \ +// RUN: | FileCheck %s --check-prefixes=BOOL-AS-CBOOL,CBOOL +// +// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_INT \ +// RUN: | FileCheck %s --check-prefixes=BOOL-AS-INT,CBOOL +// +// RUN: %clang_cc1 -verify -ast-print %s -xc -DDEF_BOOL_INT -DDIAG \ +// RUN: | FileCheck %s --check-prefixes=BOOL-AS-INT,CBOOL +// +// RUN: %clang_cc1 -verify -ast-print %s -xc++ \ +// RUN: | FileCheck %s --check-prefixes=BOOL-AS-BOOL +// +// RUN: %clang_cc1 -verify -ast-print %s -xc++ -DDIAG \ +// RUN: | FileCheck %s --check-prefixes=BOOL-AS-BOOL + +#if DEF_BOOL_CBOOL +# define bool _Bool +#elif DEF_BOOL_INT +# define bool int +#endif + +// BOOL-AS-CBOOL: _Bool i; +// BOOL-AS-INT: int i; +// BOOL-AS-BOOL: bool i; +bool i; + +#ifndef __cplusplus +// CBOOL: _Bool j; +_Bool j; +#endif + +// Induce a diagnostic (and verify we actually managed to do so), which used to +// permanently alter the -ast-print printing policy for _Bool. How bool is +// defined by the preprocessor is examined only once per compilation, when the +// diagnostic is emitted, and it used to affect the entirety of -ast-print, so +// test only one definition of bool per compilation. +#if DIAG +void fn() { 1; } // expected-warning {{expression result unused}} +#else +// expected-no-diagnostics +#endif diff --git a/test/AST/ast-print-char-literal.cpp b/test/AST/ast-print-char-literal.cpp new file mode 100644 index 0000000000000..614b3ca9d73cb --- /dev/null +++ b/test/AST/ast-print-char-literal.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -ast-print -std=c++1z %s -o - | FileCheck %s + +char c = u8'1'; +char d = '1'; +char e = U'1'; +char f = L'1'; +char g = u'1'; + +template <char c = u8'1'> +void h(); + +void i() { + h<u8'2'>(); +} + +char j = '\xFF'; + +// CHECK: char c = u8'1'; +// CHECK-NEXT: char d = '1'; +// CHECK-NEXT: char e = U'1'; +// CHECK-NEXT: char f = L'1'; +// CHECK-NEXT: char g = u'1'; + +// CHECK: template <char c = u8'1'> + +// CHECK: h<u8'2'>(); +// CHECK: char j = '\xff'; diff --git a/test/AST/ast-print-enum-decl.c b/test/AST/ast-print-enum-decl.c new file mode 100644 index 0000000000000..fba9313442850 --- /dev/null +++ b/test/AST/ast-print-enum-decl.c @@ -0,0 +1,105 @@ +// First check compiling and printing of this file. +// +// RUN: %clang_cc1 -verify -ast-print %s > %t.c +// RUN: FileCheck --check-prefixes=CHECK,PRINT %s --input-file %t.c +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 6 {{'T' is deprecated}}" >> %t.c +// RUN: echo "// expected""-note@* 6 {{'T' has been explicitly marked deprecated here}}" >> %t.c +// +// RUN: %clang_cc1 -verify -ast-print %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT %s + +// END. + +// CHECK-LABEL: defFirst +void defFirst() { + // PRINT-NEXT: enum + // PRINT-DAG: __attribute__((aligned(16))) + // PRINT-DAG: __attribute__((deprecated(""))) + // PRINT-SAME: T { + // PRINT-NEXT: E0, + // PRINT-NEXT: E1 + // PRINT-NEXT: } *p0; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} + enum __attribute__((aligned(16))) __attribute__((deprecated(""))) T { + E0, E1 + } *p0; + + // PRINT-NEXT: enum T *p1; + enum T *p1; // expected-warning {{'T' is deprecated}} +} + +// CHECK-LABEL: defLast +void defLast() { + // PRINT-NEXT: enum __attribute__((aligned(16))) T *p0; + enum __attribute__((aligned(16))) T *p0; + + // PRINT-NEXT: enum __attribute__((deprecated(""))) T { + // PRINT-NEXT: E0, + // PRINT-NEXT: E1 + // PRINT-NEXT: } *p1; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 {{'T' has been explicitly marked deprecated here}} + enum __attribute__((deprecated(""))) T { E0, E1 } *p1; +} + +// CHECK-LABEL: defMiddle +void defMiddle() { + // PRINT-NEXT: enum __attribute__((deprecated(""))) T *p0; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 3 {{'T' has been explicitly marked deprecated here}} + enum __attribute__((deprecated(""))) T *p0; + + // PRINT-NEXT: enum __attribute__((aligned(16))) T { + // PRINT-NEXT: E0 + // PRINT-NEXT: E1 + // PRINT-NEXT: } *p1; + enum __attribute__((aligned(16))) T { E0, E1 } *p1; // expected-warning {{'T' is deprecated}} + + // PRINT-NEXT: enum T *p2; + enum T *p2; // expected-warning {{'T' is deprecated}} +} + +// CHECK-LABEL: declsOnly +void declsOnly() { + // FIXME: For some reason, attributes are ignored if they're not on the first + // declaration and not on the definition. + + // PRINT-NEXT: enum __attribute__((aligned)) T *p0; + enum __attribute__((aligned)) T *p0; + + // PRINT-NEXT: enum T *p1; + enum __attribute__((may_alias)) T *p1; + + // PRINT-NEXT: enum T *p2; + enum T *p2; + + // PRINT-NEXT: enum T *p3; + enum __attribute__((deprecated(""))) T *p3; + + // PRINT-NEXT: enum T *p4; + enum T *p4; +} + +// Check that tag decl groups stay together in decl contexts. + +// PRINT-LABEL: enum DeclGroupAtFileScope { +// PRINT-NEXT: DeclGroupAtFileScope0 +// PRINT-NEXT: } *DeclGroupAtFileScopePtr; +enum DeclGroupAtFileScope { DeclGroupAtFileScope0 } *DeclGroupAtFileScopePtr; + +// PRINT-LABEL: struct DeclGroupInMemberList +struct DeclGroupInMemberList { + // PRINT-NEXT: enum T1 { + // PRINT-NEXT: T10 + // PRINT-NEXT: } *p0; + enum T1 { T10 } *p0; + // PRINT-NEXT: enum T2 { + // PRINT-NEXT: T20 + // PRINT-NEXT: } *p1, *p2; + enum T2 { T20 } *p1, *p2; + // PRINT-NEXT: }; +}; diff --git a/test/AST/ast-print-objectivec.m b/test/AST/ast-print-objectivec.m new file mode 100644 index 0000000000000..05a0a5d4aa74c --- /dev/null +++ b/test/AST/ast-print-objectivec.m @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s + +@interface NSObject @end + +@protocol P +- (void)MethP __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))); +@end + +@interface I : NSObject <P> +- (void)MethI __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))); +@end + +@interface I(CAT) +- (void)MethCAT __attribute__((availability(macosx,introduced=10_1_0,deprecated=10_2))); +@end + +@implementation I +- (void)MethP __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) {} +- (void)MethI __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) {} + +- (void)methodWithArg:(int)x andAnotherOne:(int)y { } +@end + +// CHECK: @protocol P +// CHECK: - (void)MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))); +// CHECK: @end + +// CHECK: @interface I : NSObject<P> +// CHECK: - (void)MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))); +// CHECK: @end + +// CHECK: @interface I(CAT) +// CHECK: - (void)MethCAT __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))); +// CHECK: @end + +// CHECK: @implementation I +// CHECK: - (void)MethP __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) { +// CHECK: } + +// CHECK: - (void)MethI __attribute__((availability(macos, introduced=10.1.0, deprecated=10.2))) { +// CHECK: } + +// CHECK: - (void)methodWithArg:(int)x andAnotherOne:(int)y { +// CHECK: } + +// CHECK: @end + +@class C1; +struct __attribute__((objc_bridge_related(C1,,))) S1; + +// CHECK: @class C1; +// CHECK: struct __attribute__((objc_bridge_related(C1, , ))) S1; + +@interface ImplicitPropertyWithSetterOnly + +- (void)setX:(int)x; + +@end + +void printImplicitPropertyWithSetterOnly(ImplicitPropertyWithSetterOnly *x) { + x.x = 313; // CHECK: x.x = 313; +} diff --git a/test/AST/ast-print-out-of-line-func.cpp b/test/AST/ast-print-out-of-line-func.cpp new file mode 100644 index 0000000000000..7d42f1f4037fe --- /dev/null +++ b/test/AST/ast-print-out-of-line-func.cpp @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -ast-print -std=c++14 %s | FileCheck %s + +namespace ns { + +struct Wrapper { +class Inner { + Inner(); + Inner(int); + ~Inner(); + + void operator += (int); + + template<typename T> + void member(); + + static void staticMember(); + + operator int(); + + operator ns::Wrapper(); + // CHECK: operator ns::Wrapper() +}; +}; + +Wrapper::Inner::Inner() { } +// CHECK: Wrapper::Inner::Inner() + +void Wrapper::Inner::operator +=(int) { } +// CHECK: void Wrapper::Inner::operator+=(int) + +} + +ns::Wrapper::Inner::Inner(int) { } +// CHECK: ns::Wrapper::Inner::Inner(int) + +ns::Wrapper::Inner::~Inner() { } +// CHECK: ns::Wrapper::Inner::~Inner() + +template<typename T> +void ::ns::Wrapper::Inner::member() { } +// CHECK: template <typename T> void ::ns::Wrapper::Inner::member() + +ns::Wrapper::Inner::operator int() { return 0; } +// CHECK: ns::Wrapper::Inner::operator int() + +ns::Wrapper::Inner::operator ::ns::Wrapper() { return ns::Wrapper(); } +// CHECK: ns::Wrapper::Inner::operator ::ns::Wrapper() + +namespace ns { + +void Wrapper::Inner::staticMember() { } +// CHECK: void Wrapper::Inner::staticMember() + +} + +template<int x, typename T> +class TemplateRecord { + void function(); + template<typename U> void functionTemplate(T, U); +}; + +template<int x, typename T> +void TemplateRecord<x, T>::function() { } +// CHECK: template <int x, typename T> void TemplateRecord<x, T>::function() + +template<int x, typename T> +template<typename U> +void TemplateRecord<x, T>::functionTemplate(T, U) { } +// CHECK: template <int x, typename T> template <typename U> void TemplateRecord<x, T>::functionTemplate(T, U) + +template<> +class TemplateRecord<0, int> { + void function(); + template<typename U> void functionTemplate(int, U); +}; + +void TemplateRecord<0, int>::function() { } +// CHECK: void TemplateRecord<0, int>::function() + +template<typename U> +void TemplateRecord<0, int>::functionTemplate(int, U) { } +// CHECK: template <typename U> void TemplateRecord<0, int>::functionTemplate(int, U) + +template<typename T> +struct OuterTemplateRecord { + template<typename U> + struct Inner { + void function(); + }; +}; + +template<typename T> +template<typename U> +void OuterTemplateRecord<T>::Inner<U>::function() { } +// CHECK: template <typename T> template <typename U> void OuterTemplateRecord<T>::Inner<U>::function() diff --git a/test/AST/ast-print-pragmas-xfail.cpp b/test/AST/ast-print-pragmas-xfail.cpp new file mode 100644 index 0000000000000..69ba48d0de29f --- /dev/null +++ b/test/AST/ast-print-pragmas-xfail.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -ast-print -o - | FileCheck %s + +// FIXME: Test fails because attribute order is reversed by ParsedAttributes. +// XFAIL: * + +void run1(int *List, int Length) { + int i = 0; +// CHECK: #pragma loop vectorize(4) +// CHECK-NEXT: #pragma loop interleave(8) +// CHECK-NEXT: #pragma loop vectorize(enable) +// CHECK-NEXT: #pragma loop interleave(enable) +#pragma loop vectorize(4) +#pragma loop interleave(8) +#pragma loop vectorize(enable) +#pragma loop interleave(enable) +// CHECK-NEXT: while (i < Length) + while (i < Length) { + List[i] = i; + i++; + } +} diff --git a/test/AST/ast-print-pragmas.cpp b/test/AST/ast-print-pragmas.cpp new file mode 100644 index 0000000000000..a87be2a3403f2 --- /dev/null +++ b/test/AST/ast-print-pragmas.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s +// RUN: %clang_cc1 -DMS_EXT -fsyntax-only -fms-extensions %s -triple x86_64-pc-win32 -ast-print | FileCheck %s --check-prefix=MS-EXT + +// CHECK: #pragma clang loop vectorize_width(4) +// CHECK-NEXT: #pragma clang loop interleave_count(8){{$}} + +void test(int *List, int Length) { + int i = 0; +#pragma clang loop vectorize_width(4) +#pragma clang loop interleave_count(8) +// CHECK-NEXT: while (i < Length) + while (i < Length) { + List[i] = i * 2; + i++; + } + +// CHECK: #pragma clang loop distribute(disable) +// CHECK-NEXT: #pragma clang loop vectorize(enable) +// CHECK-NEXT: #pragma clang loop interleave(disable) + +#pragma clang loop distribute(disable) +#pragma clang loop vectorize(enable) +#pragma clang loop interleave(disable) +// CHECK-NEXT: while (i - 1 < Length) + while (i - 1 < Length) { + List[i] = i * 2; + i++; + } + +// CHECK: #pragma clang loop distribute(enable) +// CHECK-NEXT: #pragma clang loop vectorize(disable) +// CHECK-NEXT: #pragma clang loop interleave(enable) + +#pragma clang loop distribute(enable) +#pragma clang loop vectorize(disable) +#pragma clang loop interleave(enable) +// CHECK-NEXT: while (i - 2 < Length) + while (i - 2 < Length) { + List[i] = i * 2; + i++; + } +} + +template <int V, int I> +void test_nontype_template_param(int *List, int Length) { +#pragma clang loop vectorize_width(V) interleave_count(I) + for (int i = 0; i < Length; i++) { + List[i] = i; + } +} + +// CHECK: #pragma clang loop vectorize_width(V) +// CHECK: #pragma clang loop interleave_count(I) + +void test_templates(int *List, int Length) { + test_nontype_template_param<2, 4>(List, Length); +} + +#ifdef MS_EXT +#pragma init_seg(compiler) +// MS-EXT: #pragma init_seg (.CRT$XCC){{$}} +// MS-EXT-NEXT: int x = 3 __declspec(thread); +int __declspec(thread) x = 3; +#endif //MS_EXT + diff --git a/test/AST/ast-print-record-decl.c b/test/AST/ast-print-record-decl.c new file mode 100644 index 0000000000000..c27fdf42f337e --- /dev/null +++ b/test/AST/ast-print-record-decl.c @@ -0,0 +1,291 @@ +// Check struct: +// +// First check compiling and printing of this file. +// +// RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm \ +// RUN: -DKW=struct -DBASES= -o - %s \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print -DKW=struct -DBASES= %s > %t.c +// RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=struct -DBASES= \ +// RUN: %s --input-file %t.c +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.c +// RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.c +// +// RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm -o - %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=struct \ +// RUN: -DBASES= %s + +// Repeat for union: +// +// First check compiling and printing of this file. +// +// RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm \ +// RUN: -DKW=union -DBASES= -o - %s \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print -DKW=union -DBASES= %s > %t.c +// RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=union -DBASES= \ +// RUN: %s --input-file %t.c +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.c +// RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.c +// +// RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm -o - %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-C -DKW=union \ +// RUN: -DBASES= %s + +// Repeat for C++ (BASES helps ensure we're printing as C++ not as C): +// +// First check compiling and printing of this file. +// +// RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm \ +// RUN: -DKW=struct -DBASES=' : B' -o - -xc++ %s \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print -DKW=struct -DBASES=' : B' -xc++ %s \ +// RUN: > %t.cpp +// RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ +// RUN: -DBASES=' : B' %s --input-file %t.cpp +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" > %t.diags +// RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.diags +// RUN: cat %t.diags >> %t.cpp +// +// RUN: %clang -target x86_64-linux -Xclang -verify -S -emit-llvm -o - %t.cpp \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print %t.cpp \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ +// RUN: -DBASES=' : B' %s +// +// Make sure implicit attributes aren't printed. See comments in inMemberPtr +// for details. +// +// RUN: %clang_cc1 -triple i686-pc-win32 -verify -ast-print -DKW=struct \ +// RUN: -DBASES=' : B' -xc++ %s > %t.cpp +// RUN: FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ +// RUN: -DBASES=' : B' %s --input-file %t.cpp +// +// RUN: cat %t.diags >> %t.cpp +// RUN: %clang_cc1 -triple i686-pc-win32 -verify -ast-print %t.cpp \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT,PRINT-CXX -DKW=struct \ +// RUN: -DBASES=' : B' %s + +// END. + +#ifndef KW +# error KW undefined +# define KW struct // help syntax checkers +#endif + +#ifndef BASES +# error BASES undefined +# define BASES // help syntax checkers +#endif + +struct B {}; + +// CHECK-LABEL: defFirst +void defFirst() { + // PRINT-NEXT: [[KW]] + // PRINT-DAG: __attribute__((aligned(16))) + // PRINT-DAG: __attribute__((deprecated(""))) + // PRINT-NOT: __attribute__ + // PRINT-SAME: T[[BASES]] { + // PRINT-NEXT: int i; + // PRINT-NEXT: } *p0; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} + KW __attribute__((aligned(16))) __attribute__((deprecated(""))) T BASES { + int i; + } *p0; + + // PRINT-NEXT: [[KW]] T *p1; + KW T *p1; // expected-warning {{'T' is deprecated}} + + // LLVM: store i64 16 + long s0 = sizeof *p0; + // LLVM-NEXT: store i64 16 + long s1 = sizeof *p1; +} + +// CHECK-LABEL: defLast +void defLast() { + // PRINT-NEXT: [[KW]] __attribute__((aligned(16))) T *p0; + KW __attribute__((aligned(16))) T *p0; + + // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T[[BASES]] { + // PRINT-NEXT: int i; + // PRINT-NEXT: } *p1; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 {{'T' has been explicitly marked deprecated here}} + KW __attribute__((deprecated(""))) T BASES { int i; } *p1; + + // LLVM: store i64 16 + long s0 = sizeof *p0; + // LLVM-NEXT: store i64 16 + long s1 = sizeof *p1; +} + +// CHECK-LABEL: defMiddle +void defMiddle() { + // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T *p0; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 3 {{'T' has been explicitly marked deprecated here}} + KW __attribute__((deprecated(""))) T *p0; + + // PRINT-NEXT: [[KW]] __attribute__((aligned(16))) T[[BASES]] { + // PRINT-NEXT: int i; + // PRINT-NEXT: } *p1; + KW __attribute__((aligned(16))) T BASES { int i; } *p1; // expected-warning {{'T' is deprecated}} + + // PRINT-NEXT: [[KW]] T *p2; + KW T *p2; // expected-warning {{'T' is deprecated}} + + // LLVM: store i64 16 + long s0 = sizeof *p0; + // LLVM-NEXT: store i64 16 + long s1 = sizeof *p1; + // LLVM-NEXT: store i64 16 + long s2 = sizeof *p2; +} + +// CHECK-LABEL: defSelfRef +void defSelfRef() { + // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T *p0; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} + KW __attribute__((deprecated(""))) T *p0; + + // PRINT-NEXT: [[KW]] __attribute__((aligned(64))) T[[BASES]] { + // PRINT-NEXT: int i; + // PRINT-NEXT: [[KW]] T *p2; + // PRINT-NEXT: [[KW]] __attribute__((may_alias)) T *p3; + // PRINT-NEXT: [[KW]] T *p4; + // PRINT-NEXT: } *p1; + KW __attribute__((aligned(64))) T BASES { // expected-warning {{'T' is deprecated}} + int i; + KW T *p2; + // FIXME: For C++, T at p3 loses aligned and deprecated, perhaps because + // that RecordDecl isn't in the same redecl list. Perhaps the redecl lists + // are split here but not in C due to the different scoping rules in C++ + // classes. + KW __attribute__((may_alias)) T *p3; + KW T *p4; + } *p1; + + // LLVM: store i64 64 + long s0 = sizeof *p0; + // LLVM-NEXT: store i64 64 + long s1 = sizeof *p1; + // LLVM-NEXT: store i64 64 + long s2 = sizeof *p0->p2; + // LLVM-NEXT: store i64 64 + long s3 = sizeof *p1->p3; + // LLVM-NEXT: store i64 64 + long s4 = sizeof *p1->p4->p2; +} + +// CHECK-LABEL: declsOnly +void declsOnly() { + // PRINT-NEXT: [[KW]] T *p0; + KW T *p0; + + // PRINT-NEXT: [[KW]] __attribute__((may_alias)) T *p1; + KW __attribute__((may_alias)) T *p1; + + // PRINT-NEXT: [[KW]] T *p2; + KW T *p2; + + // PRINT-NEXT: [[KW]] __attribute__((deprecated(""))) T *p3; + // expected-warning@+2 {{'T' is deprecated}} + // expected-note@+1 2 {{'T' has been explicitly marked deprecated here}} + KW __attribute__((deprecated(""))) T *p3; + + // PRINT-NEXT: [[KW]] T *p4; + KW T *p4; // expected-warning {{'T' is deprecated}} +} + +// Make sure expanded printing of tag types is turned back off in other parts +// of a tag declaration. The base class list is checked above. + +// CHECK-LABEL: inMembers +void inMembers() { + // PRINT-NEXT: [[KW]] T1 { + // PRINT-NEXT: int i; + // PRINT-NEXT: }; + KW T1 { int i; }; + // PRINT-NEXT: [[KW]] T2 { + // PRINT-NEXT: [[KW]] T1 i; + // PRINT-NEXT: }; + KW T2 { KW T1 i; }; +} + +// CHECK-LABEL: inInit +void inInit() { + // PRINT-NEXT: [[KW]] T1 { + // PRINT-NEXT: int i; + // PRINT-NEXT: }; + KW T1 { int i; }; + // PRINT-NEXT: [[KW]] T2 { + // PRINT-NEXT: long i; + // PRINT-NEXT: } t2 = {sizeof([[KW]] T1)}; + KW T2 { long i; } t2 = {sizeof(KW T1)}; +} + +#ifdef __cplusplus +// PRINT-CXX-LABEL: inMemberPtr +void inMemberPtr() { + // Under windows, the implicit attribute __single_inheritance used to print + // between KW and T1 here, but that wasn't faithful to the original source. + // + // PRINT-CXX-NEXT: [[KW]] T1 { + // PRINT-CXX-NEXT: int i; + // PRINT-CXX-NEXT: }; + KW T1 { int i; }; + // PRINT-CXX-NEXT: [[KW]] T2 { + // PRINT-CXX-NEXT: } T1::*p; + KW T2 {} T1::*p; +} +#endif + +// Check that tag decl groups stay together in decl contexts. + +// PRINT-LABEL: DeclGroupAtFileScope { +// PRINT-NEXT: int i; +// PRINT-NEXT: } *DeclGroupAtFileScopePtr; +KW DeclGroupAtFileScope { int i; } *DeclGroupAtFileScopePtr; + +// PRINT-LABEL: DeclGroupInMemberList { +KW DeclGroupInMemberList { + // PRINT-NEXT: struct T1 { + // PRINT-NEXT: int i; + // PRINT-NEXT: } t1; + struct T1 { int i; } t1; + // PRINT-NEXT: union T2 { + // PRINT-NEXT: int i; + // PRINT-NEXT: } *t20, t21[2]; + union T2 { int i; } *t20, t21[2]; + // PRINT-NEXT: enum T3 { + // PRINT-NEXT: T30 + // PRINT-NEXT: } t30; + enum T3 { T30 } t30; + // PRINT-NEXT: }; +}; + +// A tag decl group in the tag decl's own member list is exercised in +// defSelfRef above. diff --git a/test/AST/attr-print-emit.cpp b/test/AST/attr-print-emit.cpp new file mode 100644 index 0000000000000..cc7413baf10e8 --- /dev/null +++ b/test/AST/attr-print-emit.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 %s -ast-print | FileCheck %s +// RUN: %clang -emit-ast -o %t.ast %s +// RUN: %clang_cc1 %t.ast -ast-print | FileCheck %s + +// CHECK: void xla(int a) __attribute__((xray_log_args(1))); +void xla(int a) __attribute__((xray_log_args(1))); + +// CHECK: void *as2(int, int) __attribute__((alloc_size(1, 2))); +void *as2(int, int) __attribute__((alloc_size(1, 2))); +// CHECK: void *as1(void *, int) __attribute__((alloc_size(2))); +void *as1(void *, int) __attribute__((alloc_size(2))); + +// CHECK: void fmt(int, const char *, ...) __attribute__((format(printf, 2, 3))); +void fmt(int, const char *, ...) __attribute__((format(printf, 2, 3))); + +// CHECK: char *fmta(int, const char *) __attribute__((format_arg(2))); +char *fmta(int, const char *) __attribute__((format_arg(2))); + +// CHECK: void nn(int *, int *) __attribute__((nonnull(1, 2))); +void nn(int *, int *) __attribute__((nonnull(1, 2))); + +// CHECK: int *aa(int i) __attribute__((alloc_align(1))); +int *aa(int i) __attribute__((alloc_align(1))); + +// CHECK: void ownt(int *, int *) __attribute__((ownership_takes(foo, 1, 2))); +void ownt(int *, int *) __attribute__((ownership_takes(foo, 1, 2))); +// CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2))); +void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2))); +// CHECK: void ownr(int) __attribute__((ownership_returns(foo, 1))); +void ownr(int) __attribute__((ownership_returns(foo, 1))); + +// CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2))); +void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2))); +// CHECK: void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 1, 2))); +void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 1, 2))); + +class C { + // CHECK: void xla(int a) __attribute__((xray_log_args(2))); + void xla(int a) __attribute__((xray_log_args(2))); + + // CHECK: void *as2(int, int) __attribute__((alloc_size(2, 3))); + void *as2(int, int) __attribute__((alloc_size(2, 3))); + // CHECK: void *as1(void *, int) __attribute__((alloc_size(3))); + void *as1(void *, int) __attribute__((alloc_size(3))); + + // CHECK: void fmt(int, const char *, ...) __attribute__((format(printf, 3, 4))); + void fmt(int, const char *, ...) __attribute__((format(printf, 3, 4))); + + // CHECK: char *fmta(int, const char *) __attribute__((format_arg(3))); + char *fmta(int, const char *) __attribute__((format_arg(3))); + + // CHECK: void nn(int *, int *) __attribute__((nonnull(2, 3))); + void nn(int *, int *) __attribute__((nonnull(2, 3))); + + // CHECK: int *aa(int i) __attribute__((alloc_align(2))); + int *aa(int i) __attribute__((alloc_align(2))); + + // CHECK: void ownt(int *, int *) __attribute__((ownership_takes(foo, 2, 3))); + void ownt(int *, int *) __attribute__((ownership_takes(foo, 2, 3))); + // CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3))); + void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3))); + // CHECK: void ownr(int) __attribute__((ownership_returns(foo, 2))); + void ownr(int) __attribute__((ownership_returns(foo, 2))); + + // CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3))); + void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3))); + // CHECK: void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3))); + void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3))); +}; diff --git a/test/AST/attr-target-ast.c b/test/AST/attr-target-ast.c new file mode 100644 index 0000000000000..6e8497ea9c8d0 --- /dev/null +++ b/test/AST/attr-target-ast.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ast-dump %s | FileCheck %s + +int __attribute__((target("arch=hiss,arch=woof"))) pine_tree() { return 4; } +// CHECK-NOT: arch=hiss +// CHECK-NOT: arch=woof diff --git a/test/AST/auto-pragma.cpp b/test/AST/auto-pragma.cpp new file mode 100644 index 0000000000000..1cd0781fe9a7a --- /dev/null +++ b/test/AST/auto-pragma.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump -ast-dump-filter AutoVar | FileCheck %s + +namespace { + class foo { + }; +} + +#pragma GCC visibility push(hidden) +auto AutoVar = foo(); + +// CHECK: VarDecl {{.*}} AutoVar +// CHECK-NOT: VisibilityAttr diff --git a/test/AST/bool-type.m b/test/AST/bool-type.m new file mode 100644 index 0000000000000..830a7ef0614fc --- /dev/null +++ b/test/AST/bool-type.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple thumbv7s-apple-ios8.0 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-CHAR +// RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-BOOL +// RUN: %clang_cc1 -triple i386-apple-watchos2.0 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-BOOL +// RUN: %clang_cc1 -triple arm64-apple-ios8.0 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-BOOL +// RUN: %clang_cc1 -triple x86_64-apple-ios8.0 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-BOOL +// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-CHAR +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -ast-dump "%s" 2>&1 | FileCheck %s --check-prefix CHECK-CHAR + +// CHECK-CHAR: ObjCBoolLiteralExpr {{.*}} 'signed char' __objc_yes +// CHECK-BOOL: ObjCBoolLiteralExpr {{.*}} '_Bool' __objc_yes + +int var = __objc_yes; diff --git a/test/AST/builtins-arm-strex-rettype.c b/test/AST/builtins-arm-strex-rettype.c new file mode 100644 index 0000000000000..4ee96ce3277eb --- /dev/null +++ b/test/AST/builtins-arm-strex-rettype.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple thumbv7m-apple-darwin-eabi -ast-dump %s | FileCheck %s + +// CHECK: CallExpr {{.*}} 'int' + +void foo(int a, int *b) { + do { + } while (__builtin_arm_strex(a, b)); +} diff --git a/test/AST/c-casts.c b/test/AST/c-casts.c new file mode 100644 index 0000000000000..c3a58ed8274ca --- /dev/null +++ b/test/AST/c-casts.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -w -ast-dump %s | FileCheck %s + +// The cast construction code both for implicit and c-style casts is very +// different in C vs C++. This file is intended to test the C behavior. + +// TODO: add tests covering the rest of the code in +// Sema::CheckAssignmentConstraints and Sema::PrepareScalarCast + +// CHECK-LABEL: FunctionDecl {{.*}} cast_cvr_pointer +void cast_cvr_pointer(char volatile * __restrict * const * p) { + char*** x; + // CHECK: ImplicitCastExpr {{.*}} 'char ***' <NoOp> + x = p; + // CHECK: CStyleCastExpr {{.*}} 'char ***' <NoOp> + x = (char***)p; +} + +// CHECK-LABEL: FunctionDecl {{.*}} cast_pointer_type +void cast_pointer_type(char *p) { + void *x; + // CHECK: ImplicitCastExpr {{.*}} 'void *' <BitCast> + x = p; + // CHECK: CStyleCastExpr {{.*}} 'void *' <BitCast> + x = (void*)p; +} diff --git a/test/AST/category-attribute.m b/test/AST/category-attribute.m new file mode 100644 index 0000000000000..7efe3df00ec8a --- /dev/null +++ b/test/AST/category-attribute.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +__attribute__ ((external_source_symbol(language= "Swift", defined_in="A"))) +@interface TestInterface +@end +// CHECK: ObjCInterfaceDecl {{.*}} TestInterface +// CHECK-NEXT: ExternalSourceSymbolAttr + +__attribute__ ((external_source_symbol(language= "Swift", defined_in="B"))) +@interface TestInterface () +@end +// CHECK: ObjCCategoryDecl +// CHECK-NEXT: ObjCInterface +// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "B" + +__attribute__ ((external_source_symbol(language= "Swift", defined_in="C"))) +@interface TestInterface (Category) +@end +// CHECK: ObjCCategoryDecl +// CHECK-NEXT: ObjCInterface +// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "C" diff --git a/test/AST/coroutine-source-location-crash.cpp b/test/AST/coroutine-source-location-crash.cpp new file mode 100644 index 0000000000000..04fb1d45c524d --- /dev/null +++ b/test/AST/coroutine-source-location-crash.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \ +// RUN: -fsyntax-only -ast-dump | FileCheck %s +#include "Inputs/std-coroutine.h" + +using namespace std::experimental; + +struct A { + bool await_ready(); + void await_resume(); + template <typename F> + void await_suspend(F); +}; + +struct coro_t { + struct promise_type { + coro_t get_return_object(); + suspend_never initial_suspend(); + suspend_never final_suspend(); + void return_void(); + static void unhandled_exception(); + }; +}; + +// {{0x[0-9a-fA-F]+}} <line:[[@LINE+1]]:1, col:36> +// CHECK-LABEL: FunctionDecl {{.*}} f 'coro_t (int)' +coro_t f(int n) { + A a{}; + // CHECK: CoawaitExpr {{0x[0-9a-fA-F]+}} <col:3, col:12> + // CHECK-NEXT: DeclRefExpr {{0x[0-9a-fA-F]+}} <col:12> + // CHECK-NEXT: CXXMemberCallExpr {{0x[0-9a-fA-F]+}} <col:12> + // CHECK-NEXT: MemberExpr {{0x[0-9a-fA-F]+}} <col:12> + co_await a; +} diff --git a/test/AST/dump.cpp b/test/AST/dump.cpp new file mode 100644 index 0000000000000..b460e9325e2dd --- /dev/null +++ b/test/AST/dump.cpp @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +int ga, gb; +#pragma omp threadprivate(ga, gb) + +// CHECK: |-OMPThreadPrivateDecl {{.+}} <col:9> col:9 +// CHECK-NEXT: | |-DeclRefExpr {{.+}} <col:27> 'int' lvalue Var {{.+}} 'ga' 'int' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:31> 'int' lvalue Var {{.+}} 'gb' 'int' + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) + +#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + +// CHECK: |-OMPDeclareReductionDecl {{.+}} <line:[[@LINE-4]]:35> col:35 operator+ 'int' combiner 0x{{.+}} +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'int' lvalue Var {{.+}} 'omp_out' 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'int' lvalue Var {{.+}} 'omp_in' 'int' +// CHECK-NEXT: | |-VarDecl {{.+}} <col:35> col:35 implicit used omp_in 'int' +// CHECK-NEXT: | `-VarDecl {{.+}} <col:35> col:35 implicit used omp_out 'int' +// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <col:40> col:40 operator+ 'char' combiner 0x{{.+}} +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'char' lvalue Var {{.+}} 'omp_out' 'char' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <IntegralCast> +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'char' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'char' lvalue Var {{.+}} 'omp_in' 'char' +// CHECK-NEXT: | |-VarDecl {{.+}} <col:40> col:40 implicit used omp_in 'char' +// CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char' +// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:[[@LINE-17]]:37> col:37 fun 'float' combiner 0x{{.+}} initializer 0x{{.+}} +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float' +// CHECK-NEXT: | |-BinaryOperator {{.+}} <col:76, col:98> 'float' lvalue '=' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:76> 'float' lvalue Var {{.+}} 'omp_priv' 'float' +// CHECK-NEXT: | | `-BinaryOperator {{.+}} <col:87, col:98> 'float' '+' +// CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} <col:87> 'float' <LValueToRValue> +// CHECK-NEXT: | | | `-DeclRefExpr {{.+}} <col:87> 'float' lvalue Var {{.+}} 'omp_orig' 'float' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:98> 'float' <IntegralToFloating> +// CHECK-NEXT: | | `-IntegerLiteral {{.+}} <col:98> 'int' 15 + +struct S { + int a, b; + S() { +#pragma omp parallel for default(none) private(a) shared(b) schedule(static, a) + for (int i = 0; i < 0; ++i) + ++a; + } +}; + +// CHECK: | `-OMPParallelForDirective {{.+}} {{<line:.+:9, col:80>|<col:9, col:80>}} +// CHECK-NEXT: | |-OMPDefaultClause {{.+}} <col:26, col:38> +// CHECK-NEXT: | |-OMPPrivateClause {{.+}} <col:40, col:49> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:48> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &' +// CHECK-NEXT: | |-OMPSharedClause {{.+}} <col:51, col:59> +// CHECK-NEXT: | | `-MemberExpr {{.+}} <col:58> 'int' lvalue ->b +// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'S *' this +// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79> +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int' +// CHECK-NEXT: | `-CapturedStmt {{.+}} <line:[[@LINE-15]]:5, line:[[@LINE-14]]:9> +// CHECK-NEXT: | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc> +// CHECK-NEXT: | | |-ForStmt {{.+}} <line:[[@LINE-17]]:5, line:[[@LINE-16]]:9> +// CHECK: | | | `-UnaryOperator {{.+}} <line:[[@LINE-17]]:7, col:9> 'int' lvalue prefix '++' +// CHECK-NEXT: | | | `-DeclRefExpr {{.+}} <col:9> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &' + +#pragma omp declare simd +#pragma omp declare simd inbranch +void foo(); + +// CHECK: |-FunctionDecl {{.+}} <line:[[@LINE-2]]:1, col:10> col:6 foo 'void ()' +// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:[[@LINE-4]]:9, col:34> Implicit BS_Inbranch +// CHECK: `-OMPDeclareSimdDeclAttr {{.+}} <line:[[@LINE-6]]:9, col:25> Implicit BS_Undefined + +#pragma omp declare target +int bar() { + int f; + return f; +} +#pragma omp end declare target + +// CHECK: `-FunctionDecl {{.+}} <line:[[@LINE-6]]:1, line:[[@LINE-3]]:1> line:[[@LINE-6]]:5 bar 'int ()' +// CHECK-NEXT: |-CompoundStmt {{.+}} <col:11, line:[[@LINE-4]]:1> +// CHECK-NEXT: | |-DeclStmt {{.+}} <line:[[@LINE-7]]:3, col:8> +// CHECK-NEXT: | | `-VarDecl {{.+}} <col:3, col:7> col:7 used f 'int' +// CHECK-NEXT: | `-ReturnStmt {{.+}} <line:[[@LINE-8]]:3, col:10> +// CHECK-NEXT: | `-ImplicitCastExpr {{.+}} <col:10> 'int' <LValueToRValue> +// CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:10> 'int' lvalue Var {{.+}} 'f' 'int' +// CHECK-NEXT: `-OMPDeclareTargetDeclAttr {{.+}} <<invalid sloc>> Implicit MT_To diff --git a/test/AST/finally-msvc.m b/test/AST/finally-msvc.m new file mode 100644 index 0000000000000..5db08a7f71001 --- /dev/null +++ b/test/AST/finally-msvc.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple i686--windows-msvc -fexceptions -fobjc-exceptions -ast-dump %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64--windows-msvc -fexceptions -fobjc-exceptions -ast-dump %s 2>&1 | FileCheck %s + +void f() { + @try { + } @finally { + } +} + +// CHECK: ObjCAtFinallyStmt +// CHECK-NEXT: CapturedStmt +// CHECK-NEXT: CapturedDecl +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: ImplicitParamDecl diff --git a/test/AST/fixed_point.c b/test/AST/fixed_point.c new file mode 100644 index 0000000000000..3a67718fba8ec --- /dev/null +++ b/test/AST/fixed_point.c @@ -0,0 +1,399 @@ +// RUN: %clang_cc1 -x c -ffixed-point -ast-dump %s | FileCheck %s --strict-whitespace + +/* Various contexts where type _Accum can appear. */ + +// Primary fixed point types +signed short _Accum s_short_accum; +signed _Accum s_accum; +signed long _Accum s_long_accum; +unsigned short _Accum u_short_accum; +unsigned _Accum u_accum; +unsigned long _Accum u_long_accum; +signed short _Fract s_short_fract; +signed _Fract s_fract; +signed long _Fract s_long_fract; +unsigned short _Fract u_short_fract; +unsigned _Fract u_fract; +unsigned long _Fract u_long_fract; + +// Aliased fixed point types +short _Accum short_accum; +_Accum accum; +long _Accum long_accum; +short _Fract short_fract; +_Fract fract; +long _Fract long_fract; + +// Saturated fixed point types +_Sat signed short _Accum sat_s_short_accum; +_Sat signed _Accum sat_s_accum; +_Sat signed long _Accum sat_s_long_accum; +_Sat unsigned short _Accum sat_u_short_accum; +_Sat unsigned _Accum sat_u_accum; +_Sat unsigned long _Accum sat_u_long_accum; +_Sat signed short _Fract sat_s_short_fract; +_Sat signed _Fract sat_s_fract; +_Sat signed long _Fract sat_s_long_fract; +_Sat unsigned short _Fract sat_u_short_fract; +_Sat unsigned _Fract sat_u_fract; +_Sat unsigned long _Fract sat_u_long_fract; + +// Aliased saturated fixed point types +_Sat short _Accum sat_short_accum; +_Sat _Accum sat_accum; +_Sat long _Accum sat_long_accum; +_Sat short _Fract sat_short_fract; +_Sat _Fract sat_fract; +_Sat long _Fract sat_long_fract; + +//CHECK: |-VarDecl {{.*}} s_short_accum 'short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum' +//CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} s_short_fract 'short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} s_fract '_Fract' +//CHECK-NEXT: |-VarDecl {{.*}} s_long_fract 'long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} u_short_fract 'unsigned short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} u_fract 'unsigned _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} u_long_fract 'unsigned long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum' +//CHECK-NEXT: |-VarDecl {{.*}} long_accum 'long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} short_fract 'short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} fract '_Fract' +//CHECK-NEXT: |-VarDecl {{.*}} long_fract 'long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_s_short_accum '_Sat short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_s_accum '_Sat _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_s_long_accum '_Sat long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_u_short_accum '_Sat unsigned short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_u_accum '_Sat unsigned _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_u_long_accum '_Sat unsigned long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_s_short_fract '_Sat short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_s_fract '_Sat _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_s_long_fract '_Sat long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_u_short_fract '_Sat unsigned short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_u_fract '_Sat unsigned _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_u_long_fract '_Sat unsigned long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_short_accum '_Sat short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_accum '_Sat _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_long_accum '_Sat long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sat_short_fract '_Sat short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_fract '_Sat _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sat_long_fract '_Sat long _Fract' + +#define MIX_TYPE_SPEC(SPEC, SIGN, SIZE, ID) \ + SPEC SIGN SIZE _Accum ID; \ + SIGN SPEC SIZE _Accum ID ## 2; \ + SIGN SIZE SPEC _Accum ID ## 3; \ + SIGN SIZE _Accum SPEC ID ## 4; + +/* Mixing fixed point types with other type specifiers */ + +#define MIX_VOLATILE(SIGN, SIZE, ID) MIX_TYPE_SPEC(volatile, SIGN, SIZE, ID) +#define MIX_ATOMIC(SIGN, SIZE, ID) MIX_TYPE_SPEC(_Atomic, SIGN, SIZE, ID) +#define MIX_CONST(SIGN, SIZE, ID) MIX_TYPE_SPEC(const, SIGN, SIZE, ID) + +MIX_VOLATILE(signed, short, vol_s_short_accum) +MIX_ATOMIC(signed, short, atm_s_short_accum) +MIX_CONST(signed, short, const_s_short_accum) + +// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum 'volatile short _Accum' +// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum2 'volatile short _Accum' +// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum3 'volatile short _Accum' +// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum4 'volatile short _Accum' + +// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum '_Atomic(short _Accum)' +// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum2 '_Atomic(short _Accum)' +// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum3 '_Atomic(short _Accum)' +// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum4 '_Atomic(short _Accum)' + +// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum 'const short _Accum' +// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum2 'const short _Accum' +// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum3 'const short _Accum' +// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum4 'const short _Accum' + +/* Typedefs */ + +// Primary fixed point types +typedef signed short _Accum SsA_t; +typedef signed _Accum SA_t; +typedef signed long _Accum SlA_t; +typedef unsigned short _Accum UsA_t; +typedef unsigned _Accum UA_t; +typedef unsigned long _Accum UlA_t; +typedef signed short _Fract SsF_t; +typedef signed _Fract SF_t; +typedef signed long _Fract SlF_t; +typedef unsigned short _Fract UsF_t; +typedef unsigned _Fract UF_t; +typedef unsigned long _Fract UlF_t; + +// Aliased fixed point types +typedef short _Accum sA_t; +typedef _Accum A_t; +typedef long _Accum lA_t; +typedef short _Fract sF_t; +typedef _Fract F_t; +typedef long _Fract lF_t; + +// Saturated fixed point types +typedef _Sat signed short _Accum SatSsA_t; +typedef _Sat signed _Accum SatSA_t; +typedef _Sat signed long _Accum SatSlA_t; +typedef _Sat unsigned short _Accum SatUsA_t; +typedef _Sat unsigned _Accum SatUA_t; +typedef _Sat unsigned long _Accum SatUlA_t; +typedef _Sat signed short _Fract SatSsF_t; +typedef _Sat signed _Fract SatSF_t; +typedef _Sat signed long _Fract SatSlF_t; +typedef _Sat unsigned short _Fract SatUsF_t; +typedef _Sat unsigned _Fract SatUF_t; +typedef _Sat unsigned long _Fract SatUlF_t; + +// Aliased saturated fixed point types +typedef _Sat short _Accum SatsA_t; +typedef _Sat _Accum SatA_t; +typedef _Sat long _Accum SatlA_t; +typedef _Sat short _Fract SatsF_t; +typedef _Sat _Fract SatF_t; +typedef _Sat long _Fract SatlF_t; + +SsA_t SsA_type; +SA_t SA_type; +SlA_t SlA_type; +UsA_t UsA_type; +UA_t UA_type; +UlA_t UlA_type; +SsF_t SsF_type; +SF_t SF_type; +SlF_t SlF_type; +UsF_t UsF_type; +UF_t UF_type; +UlF_t UlF_type; + +sA_t sA_type; +A_t A_type; +lA_t lA_type; +sF_t sF_type; +F_t F_type; +lF_t lF_type; + +SatSsA_t SatSsA_type; +SatSA_t SatSA_type; +SatSlA_t SatSlA_type; +SatUsA_t SatUsA_type; +SatUA_t SatUA_type; +SatUlA_t SatUlA_type; +SatSsF_t SatSsF_type; +SatSF_t SatSF_type; +SatSlF_t SatSlF_type; +SatUsF_t SatUsF_type; +SatUF_t SatUF_type; +SatUlF_t SatUlF_type; + +SatsA_t SatsA_type; +SatA_t SatA_type; +SatlA_t SatlA_type; +SatsF_t SatsF_type; +SatF_t SatF_type; +SatlF_t SatlF_type; + +//CHECK: |-VarDecl {{.*}} SsA_type 'SsA_t':'short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SA_type 'SA_t':'_Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SlA_type 'SlA_t':'long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} UsA_type 'UsA_t':'unsigned short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} UA_type 'UA_t':'unsigned _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} UlA_type 'UlA_t':'unsigned long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SsF_type 'SsF_t':'short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SF_type 'SF_t':'_Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SlF_type 'SlF_t':'long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} UsF_type 'UsF_t':'unsigned short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} UF_type 'UF_t':'unsigned _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} UlF_type 'UlF_t':'unsigned long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} sA_type 'sA_t':'short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} A_type 'A_t':'_Accum' +//CHECK-NEXT: |-VarDecl {{.*}} lA_type 'lA_t':'long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} sF_type 'sF_t':'short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} F_type 'F_t':'_Fract' +//CHECK-NEXT: |-VarDecl {{.*}} lF_type 'lF_t':'long _Fract' + +//CHECK-NEXT: |-VarDecl {{.*}} SatSsA_type 'SatSsA_t':'_Sat short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatSA_type 'SatSA_t':'_Sat _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatSlA_type 'SatSlA_t':'_Sat long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatUsA_type 'SatUsA_t':'_Sat unsigned short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatUA_type 'SatUA_t':'_Sat unsigned _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatUlA_type 'SatUlA_t':'_Sat unsigned long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatSsF_type 'SatSsF_t':'_Sat short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatSF_type 'SatSF_t':'_Sat _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatSlF_type 'SatSlF_t':'_Sat long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatUsF_type 'SatUsF_t':'_Sat unsigned short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatUF_type 'SatUF_t':'_Sat unsigned _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatUlF_type 'SatUlF_t':'_Sat unsigned long _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatsA_type 'SatsA_t':'_Sat short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatA_type 'SatA_t':'_Sat _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatlA_type 'SatlA_t':'_Sat long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} SatsF_type 'SatsF_t':'_Sat short _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatF_type 'SatF_t':'_Sat _Fract' +//CHECK-NEXT: |-VarDecl {{.*}} SatlF_type 'SatlF_t':'_Sat long _Fract' + +// Fixed point literal exponent syntax +_Accum decexp1 = 1.575e1k; +_Accum decexp2 = 1.575E1k; +_Accum decexp3 = 1575e-2k; +_Accum decexp4 = 1575E-2k; + +_Accum hexexp1 = 0x0.3p10k; +_Accum hexexp2 = 0x0.3P10k; +_Accum hexexp3 = 0x30000p-10k; +_Accum hexexp4 = 0x30000P-10k; + +_Accum zeroexp1 = 1e0k; +_Accum zeroexp2 = 1e-0k; + +//CHECK-NEXT: |-VarDecl {{.*}} decexp1 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 +//CHECK-NEXT: |-VarDecl {{.*}} decexp2 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 +//CHECK-NEXT: |-VarDecl {{.*}} decexp3 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 +//CHECK-NEXT: |-VarDecl {{.*}} decexp4 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75 + +//CHECK-NEXT: |-VarDecl {{.*}} hexexp1 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 +//CHECK-NEXT: |-VarDecl {{.*}} hexexp2 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 +//CHECK-NEXT: |-VarDecl {{.*}} hexexp3 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 +//CHECK-NEXT: |-VarDecl {{.*}} hexexp4 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0 + +//CHECK-NEXT: |-VarDecl {{.*}} zeroexp1 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0 +//CHECK-NEXT: |-VarDecl {{.*}} zeroexp2 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0 + +// Fixed point literal values +_Accum literal1 = 2.5k; // Precise decimal +_Accum literal2 = 0.0k; // Zero +_Accum literal3 = 1.1k; // Imprecise decimal +_Accum literal4 = 1.11k; +_Accum literal5 = 1.111k; +_Accum literal6 = 1.1111k; +_Accum literal7 = 1.11111k; // After some point after the radix, adding any more + // digits to the literal will not result in any + // further precision since the nth digit added may + // be less than the precision that can be + // represented by the fractional bits of the type. + // This results in the same value being stored for + // the type. + +//CHECK-NEXT: |-VarDecl {{.*}} literal1 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 2.5 +//CHECK-NEXT: |-VarDecl {{.*}} literal2 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.0 +//CHECK-NEXT: |-VarDecl {{.*}} literal3 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0999755859375 +//CHECK-NEXT: |-VarDecl {{.*}} literal4 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.1099853515625 +//CHECK-NEXT: |-VarDecl {{.*}} literal5 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.110992431640625 +//CHECK-NEXT: |-VarDecl {{.*}} literal6 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375 +//CHECK-NEXT: |-VarDecl {{.*}} literal7 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375 + +long _Accum longaccumliteral = 0.99999999lk; +long _Accum longaccumliteral2 = 0.999999999lk; +long _Accum verylongaccumliteral = 0.99999999999999999999999999lk; +long _Fract longfractliteral = 0.99999999lr; +long _Fract longfractliteral2 = 0.999999999lr; +long _Fract verylongfractliteral = 0.99999999999999999999999999lr; + +//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral 'long _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.999999989755451679229736328125 +//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral2 'long _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999986030161380767822265625 +//CHECK-NEXT: |-VarDecl {{.*}} verylongaccumliteral 'long _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875 +//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral 'long _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.999999989755451679229736328125 +//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral2 'long _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999986030161380767822265625 +//CHECK-NEXT: |-VarDecl {{.*}} verylongfractliteral 'long _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875 + +unsigned _Accum uliteral1 = 2.5uk; // Unsigned +_Accum literal8 = -2.5k; // Negative + +//CHECK-NEXT: |-VarDecl {{.*}} uliteral1 'unsigned _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned _Accum' 2.5 +//CHECK-NEXT: |-VarDecl {{.*}} literal8 '_Accum' cinit +//CHECK-NEXT: `-UnaryOperator {{.*}} '_Accum' prefix '-' +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 2.5 + +short _Accum literalexact1 = 0.9921875hk; // Exact value +_Accum literalexact2 = 0.999969482421875k; + +//CHECK-NEXT: |-VarDecl {{.*}} literalexact1 'short _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.9921875 +//CHECK-NEXT: |-VarDecl {{.*}} literalexact2 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.999969482421875 + +// Unfortunately we do not have enough space to store the exact decimal value of +// 0.9999999995343387126922607421875 ((1 << 31) - 1), but we can still use a +// large number of 9s to get the max fractional value. +long _Accum long_accum_max = 0.999999999999999999999999999lk; + +//CHECK-NEXT: |-VarDecl {{.*}} long_accum_max 'long _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875 + +// Epsilon +short _Accum short_accum_eps = 0.0078125hk; +short _Accum short_accum_eps2 = 0.0078124hk; // Less than epsilon floors to zero +_Accum accum_eps = 0.000030517578125k; +_Accum accum_eps2 = 0.000030517578124k; +long _Accum long_accum_eps = 0x1p-31lk; +long _Accum long_accum_eps2 = 0x0.99999999p-31lk; + +//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps 'short _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.0078125 +//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps2 'short _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.0 +//CHECK-NEXT: |-VarDecl {{.*}} accum_eps '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.000030517578125 +//CHECK-NEXT: |-VarDecl {{.*}} accum_eps2 '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.0 +//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps 'long _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.0000000004656612873077392578125 +//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps2 'long _Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.0 + +// Fract literals can be one but evaluate to the respective Fract max +short _Fract short_fract_one = 1.0hr; +_Fract fract_one = 1.0r; +long _Fract long_fract_one = 1.0lr; +unsigned short _Fract u_short_fract_one = 1.0uhr; +unsigned _Fract u_fract_one = 1.0ur; +unsigned long _Fract u_long_fract_one = 1.0ulr; + +//CHECK-NEXT: |-VarDecl {{.*}} short_fract_one 'short _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Fract' 0.9921875 +//CHECK-NEXT: |-VarDecl {{.*}} fract_one '_Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Fract' 0.999969482421875 +//CHECK-NEXT: |-VarDecl {{.*}} long_fract_one 'long _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875 + +//CHECK-NEXT: |-VarDecl {{.*}} u_short_fract_one 'unsigned short _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned short _Fract' 0.99609375 +//CHECK-NEXT: |-VarDecl {{.*}} u_fract_one 'unsigned _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned _Fract' 0.9999847412109375 +//CHECK-NEXT: |-VarDecl {{.*}} u_long_fract_one 'unsigned long _Fract' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned long _Fract' 0.99999999976716935634613037109375 + +_Accum literallast = 1.0k; // One + +//CHECK-NEXT: `-VarDecl {{.*}} literallast '_Accum' cinit +//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0 diff --git a/test/AST/fixed_point_to_string.c b/test/AST/fixed_point_to_string.c new file mode 100644 index 0000000000000..ad71d1024f537 --- /dev/null +++ b/test/AST/fixed_point_to_string.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -ast-dump -ffixed-point %s | FileCheck %s +// RUN: %clang_cc1 -ast-dump -ffixed-point -fpadding-on-unsigned-fixed-point %s | FileCheck %s + +/** + * Check the same values are printed in the AST regardless of if unsigned types + * have the same number of fractional bits as signed types. + */ + +unsigned short _Accum u_short_accum = 0.5uhk; +unsigned _Accum u_accum = 0.5uk; +unsigned long _Accum u_long_accum = 0.5ulk; +unsigned short _Fract u_short_fract = 0.5uhr; +unsigned _Fract u_fract = 0.5ur; +unsigned long _Fract u_long_fract = 0.5ulr; + +//CHECK: FixedPointLiteral {{.*}} 'unsigned short _Accum' 0.5 +//CHECK: FixedPointLiteral {{.*}} 'unsigned _Accum' 0.5 +//CHECK: FixedPointLiteral {{.*}} 'unsigned long _Accum' 0.5 +//CHECK: FixedPointLiteral {{.*}} 'unsigned short _Fract' 0.5 +//CHECK: FixedPointLiteral {{.*}} 'unsigned _Fract' 0.5 +//CHECK: FixedPointLiteral {{.*}} 'unsigned long _Fract' 0.5 diff --git a/test/AST/float16.cpp b/test/AST/float16.cpp new file mode 100644 index 0000000000000..aa65270c75d4c --- /dev/null +++ b/test/AST/float16.cpp @@ -0,0 +1,326 @@ +// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace
+
+/* Various contexts where type _Float16 can appear. */
+
+/* Namespace */
+namespace {
+ _Float16 f1n;
+ _Float16 f2n = 33.f16;
+ _Float16 arr1n[10];
+ _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
+ const volatile _Float16 func1n(const _Float16 &arg) {
+ return arg + f2n + arr1n[4] - arr2n[1];
+ }
+}
+
+//CHECK: |-NamespaceDecl
+//CHECK-NEXT: | |-VarDecl {{.*}} f1n '_Float16'
+//CHECK-NEXT: | |-VarDecl {{.*}} f2n '_Float16' cinit
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 3.300000e+01
+//CHECK-NEXT: | |-VarDecl {{.*}} arr1n '_Float16 [10]'
+//CHECK-NEXT: | |-VarDecl {{.*}} arr2n '_Float16 [3]' cinit
+//CHECK-NEXT: | | `-InitListExpr {{.*}} '_Float16 [3]'
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
+//CHECK-NEXT: | `-FunctionDecl {{.*}} func1n 'const volatile _Float16 (const _Float16 &)'
+
+/* File */
+_Float16 f1f;
+_Float16 f2f = 32.4;
+_Float16 arr1f[10];
+_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
+_Float16 func1f(_Float16 arg);
+
+//CHECK: |-VarDecl {{.*}} f1f '_Float16'
+//CHECK-NEXT: |-VarDecl {{.*}} f2f '_Float16' cinit
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.240000e+01
+//CHECK-NEXT: |-VarDecl {{.*}} arr1f '_Float16 [10]'
+//CHECK-NEXT: |-VarDecl {{.*}} arr2f '_Float16 [3]' cinit
+//CHECK-NEXT: | `-InitListExpr {{.*}} '_Float16 [3]'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
+//CHECK-NEXT: |-FunctionDecl {{.*}} func1f '_Float16 (_Float16)'
+//CHECK-NEXT: | `-ParmVarDecl {{.*}} arg '_Float16'
+
+
+// Mixing __fp16 and Float16 types:
+// The _Float16 type is first converted to __fp16 type and then the operation
+// is completed as if both operands were of __fp16 type.
+
+__fp16 B = -0.1;
+auto C = -1.0f16 + B;
+
+// When we do *not* have native half types, we expect __fp16 to be promoted to
+// float, and consequently also _Float16 promotions to float:
+
+//CHECK: -VarDecl {{.*}} used B '__fp16' cinit
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
+//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
+//CHECK-NEXT: |-VarDecl {{.*}} C 'float':'float' cinit
+//CHECK-NEXT: | `-BinaryOperator {{.*}} 'float' '+'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
+
+// When do have native half types, we expect to see promotions to fp16:
+
+//CHECK-NATIVE: |-VarDecl {{.*}} used B '__fp16' cinit
+//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
+//CHECK-NATIVE: | `-UnaryOperator {{.*}} 'double' prefix '-'
+//CHECK-NATIVE: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
+//CHECK-NATIVE: |-VarDecl {{.*}} C '__fp16':'__fp16' cinit
+//CHECK-NATIVE: | `-BinaryOperator {{.*}} '__fp16' '+'
+//CHECK-NATIVE: | |-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
+//CHECK-NATIVE: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NATIVE: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
+//CHECK-NATIVE: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
+
+
+/* Class */
+
+class C1 {
+ _Float16 f1c;
+ static const _Float16 f2c;
+ volatile _Float16 f3c;
+public:
+ C1(_Float16 arg) : f1c(arg), f3c(arg) { }
+ _Float16 func1c(_Float16 arg ) {
+ return f1c + arg;
+ }
+ static _Float16 func2c(_Float16 arg) {
+ return arg * C1::f2c;
+ }
+};
+
+//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition
+//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1
+//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16'
+//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static
+//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16'
+//CHECK-NEXT: | |-AccessSpecDecl
+//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} used C1 'void (_Float16)
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
+//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f1c' '_Float16'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f3c' 'volatile _Float16'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func1c '_Float16 (_Float16)
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | | `-ReturnStmt
+//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}}
+//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'C1 *' this
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | | `-ReturnStmt
+//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '*'
+//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const _Float16' lvalue Var 0x{{.*}} 'f2c' 'const _Float16'
+
+
+/* Template */
+
+template <class C> C func1t(C arg) {
+ return arg * 2.f16;
+}
+
+//CHECK: |-FunctionTemplateDecl {{.*}} func1t
+//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} C
+//CHECK-NEXT: | |-FunctionDecl {{.*}} func1t 'C (C)'
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} referenced arg 'C'
+//CHECK-NEXT: | | `-CompoundStmt
+//CHECK-NEXT: | | `-ReturnStmt
+//CHECK-NEXT: | | `-BinaryOperator {{.*}} '<dependent type>' '*'
+//CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'C' lvalue ParmVar {{.*}} 'arg' 'C'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
+//CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)'
+//CHECK-NEXT: | |-TemplateArgument type '_Float16'
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16'
+//CHECK-NEXT: | `-CompoundStmt
+//CHECK-NEXT: | `-ReturnStmt
+//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16':'_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16':'_Float16' lvalue ParmVar {{.*}} 'arg' '_Float16':'_Float16'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
+
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+//CHECK: |-ClassTemplateDecl {{.*}} S1
+//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C
+//CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition
+//CHECK: | | |-CXXRecordDecl {{.*}} implicit struct S1
+//CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C'
+//CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1'
+
+template <> struct S1<_Float16> {
+ _Float16 mem2;
+};
+
+
+/* Local */
+
+extern int printf (const char *__restrict __format, ...);
+
+int main(void) {
+ _Float16 f1l = 1e3f16;
+//CHECK: | `-VarDecl {{.*}} used f1l '_Float16' cinit
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+03
+
+ _Float16 f2l = -0.f16;
+//CHECK: | `-VarDecl {{.*}} used f2l '_Float16' cinit
+//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
+
+ _Float16 f3l = 1.000976562;
+//CHECK: | `-VarDecl {{.*}} used f3l '_Float16' cinit
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000977e+00
+
+ C1 c1(f1l);
+//CHECK: | `-VarDecl{{.*}} used c1 'C1' callinit
+//CHECK-NEXT: | `-CXXConstructExpr {{.*}} 'C1' 'void (_Float16)
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var 0x{{.*}} 'f1l' '_Float16'
+
+ S1<_Float16> s1 = { 132.f16 };
+//CHECK: | `-VarDecl {{.*}} used s1 'S1<_Float16>':'S1<_Float16>' cinit
+//CHECK-NEXT: | `-InitListExpr {{.*}} 'S1<_Float16>':'S1<_Float16>'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.320000e+02
+
+ _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
+ func1t(f1l) + s1.mem2 - f1n + f2n;
+//CHECK: | `-VarDecl {{.*}} used f4l '_Float16' cinit
+//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | |-BinaryOperator {{.*}} '_Float16' '-'
+//CHECK-NEXT: | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
+//CHECK-NEXT: | | | | | | | |-CallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} 'const volatile _Float16 (*)(const _Float16 &)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} 'const volatile _Float16 (const _Float16 &)' lvalue Function {{.*}} 'func1n' 'const volatile _Float16 (const _Float16 &)'
+//CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} 'const _Float16' lvalue <NoOp>
+//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
+//CHECK-NEXT: | | | | | | | `-CallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1f' '_Float16 (_Float16)'
+//CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
+//CHECK-NEXT: | | | | | | `-CXXMemberCallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | | |-MemberExpr {{.*}} '<bound member function type>' .func1c {{.*}}
+//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} 'C1' lvalue Var {{.*}} 'c1' 'C1'
+//CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
+//CHECK-NEXT: | | | | | `-CallExpr {{.*}} '_Float16'
+//CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | | `-MemberExpr {{.*}} '_Float16 (_Float16)' lvalue .func2c {{.*}}
+//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} 'C1' lvalue Var {{.*}} 'c1' 'C1'
+//CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
+//CHECK-NEXT: | | | | `-CallExpr {{.*}} '_Float16':'_Float16'
+//CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
+//CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue .mem2 {{.*}}
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S1<_Float16>':'S1<_Float16>' lvalue Var {{.*}} 's1' 'S1<_Float16>':'S1<_Float16>'
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1n' '_Float16'
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
+//CHECK: | |-VarDecl {{.*}} f5l '_Float16':'_Float16' cinit
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NEXT: | |-VarDecl {{.*}} f6l '_Float16 *' cinit
+//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16 *' prefix '&'
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
+//CHECK-NEXT: | `-VarDecl {{.*}} f7l '_Float16':'_Float16' cinit
+//CHECK-NEXT: | `-CallExpr {{.*}} '_Float16':'_Float16'
+//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
+
+ _Float16 f8l = f4l++;
+//CHECK: | `-VarDecl {{.*}} f8l '_Float16' cinit
+//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' postfix '++'
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f4l' '_Float16'
+
+ _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
+//CHECK: `-VarDecl {{.*}} arr1l '_Float16 [3]' cinit
+//CHECK-NEXT: `-InitListExpr {{.*}} '_Float16 [3]'
+//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
+//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
+//CHECK-NEXT: `-UnaryOperator {{.*}} '_Float16' prefix '-'
+//CHECK-NEXT: `-FloatingLiteral {{.*}} '_Float16' 1.100000e+01
+
+ float cvtf = f2n;
+//CHECK: `-VarDecl {{.*}} cvtf 'float' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ double cvtd = f2n;
+//CHECK: `-VarDecl {{.*}} cvtd 'double' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' <FloatingCast>
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ long double cvtld = f2n;
+//CHECK: `-VarDecl {{.*}} cvtld 'long double' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'long double' <FloatingCast>
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
+
+ _Float16 f2h = 42.0f;
+//CHECK: `-VarDecl {{.*}} f2h '_Float16' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: `-FloatingLiteral {{.*}} 'float' 4.200000e+01
+
+ _Float16 d2h = 42.0;
+//CHECK: `-VarDecl {{.*}} d2h '_Float16' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: `-FloatingLiteral {{.*}} 'double' 4.200000e+01
+
+ _Float16 ld2h = 42.0l;
+//CHECK: `-VarDecl {{.*}} ld2h '_Float16' cinit
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
+//CHECK-NEXT: `-FloatingLiteral {{.*}} 'long double' 4.200000e+01
+}
diff --git a/test/AST/foreachtemplatized.mm b/test/AST/foreachtemplatized.mm new file mode 100644 index 0000000000000..ab2770a7cefb6 --- /dev/null +++ b/test/AST/foreachtemplatized.mm @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -std=c++11 -ast-dump %s | FileCheck %s + +// CHECK-NOT: ImplicitValueInitExpr + +@interface I +@end + +template <typename T> +void decode(I *p) { + for (I *k in p) {} +} + +void decode(I *p) { + decode<int>(p); +} diff --git a/test/AST/implicit-cast-dump.c b/test/AST/implicit-cast-dump.c new file mode 100644 index 0000000000000..4cd855fb1d46d --- /dev/null +++ b/test/AST/implicit-cast-dump.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -ast-dump %s | FileCheck %s + +void foo1(void*); +void foo2(void* const); + + +void bar() { + // CHECK: FunctionDecl {{.*}} <line:{{.*}}, line:{{.*}}> line:{{.*}} bar 'void ()' + + foo1(0); + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer> + + foo2(0); + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer> +} diff --git a/test/AST/multistep-explicit-cast.c b/test/AST/multistep-explicit-cast.c new file mode 100644 index 0000000000000..aeb5919618126 --- /dev/null +++ b/test/AST/multistep-explicit-cast.c @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s + +// We are checking that implicit casts don't get marked with 'part_of_explicit_cast', +// while in explicit casts, the implicitly-inserted implicit casts are marked with 'part_of_explicit_cast' + +unsigned char implicitcast_0(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_0 'unsigned char (unsigned int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return x; +} + +signed char implicitcast_1(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_1 'signed char (unsigned int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return x; +} + +unsigned char implicitcast_2(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_2 'unsigned char (int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return x; +} + +signed char implicitcast_3(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_3 'signed char (int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return x; +} + +//----------------------------------------------------------------------------// + +unsigned char cstylecast_0(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_0 'unsigned char (unsigned int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return (unsigned char)x; +} + +signed char cstylecast_1(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_1 'signed char (unsigned int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return (signed char)x; +} + +unsigned char cstylecast_2(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_2 'unsigned char (int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return (unsigned char)x; +} + +signed char cstylecast_3(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_3 'signed char (int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return (signed char)x; +} diff --git a/test/AST/multistep-explicit-cast.cpp b/test/AST/multistep-explicit-cast.cpp new file mode 100644 index 0000000000000..58466791354c5 --- /dev/null +++ b/test/AST/multistep-explicit-cast.cpp @@ -0,0 +1,155 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s + +// We are checking that implicit casts don't get marked with 'part_of_explicit_cast', +// while in explicit casts, the implicitly-inserted implicit casts are marked with 'part_of_explicit_cast' + +unsigned char implicitcast_0(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_0 'unsigned char (unsigned int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return x; +} + +signed char implicitcast_1(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_1 'signed char (unsigned int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return x; +} + +unsigned char implicitcast_2(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_2 'unsigned char (int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return x; +} + +signed char implicitcast_3(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_3 'signed char (int)'{{$}} + // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return x; +} + +//----------------------------------------------------------------------------// + +unsigned char cstylecast_0(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_0 'unsigned char (unsigned int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return (unsigned char)x; +} + +signed char cstylecast_1(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_1 'signed char (unsigned int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return (signed char)x; +} + +unsigned char cstylecast_2(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_2 'unsigned char (int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return (unsigned char)x; +} + +signed char cstylecast_3(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_3 'signed char (int)'{{$}} + // CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return (signed char)x; +} + +//----------------------------------------------------------------------------// + +unsigned char cxxstaticcast_0(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_0 'unsigned char (unsigned int)'{{$}} + // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'unsigned char' static_cast<unsigned char> <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return static_cast<unsigned char>(x); +} + +signed char cxxstaticcast_1(unsigned int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_1 'signed char (unsigned int)'{{$}} + // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'signed char' static_cast<signed char> <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}} + return static_cast<signed char>(x); +} + +unsigned char cxxstaticcast_2(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_2 'unsigned char (int)'{{$}} + // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'unsigned char' static_cast<unsigned char> <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return static_cast<unsigned char>(x); +} + +signed char cxxstaticcast_3(signed int x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_3 'signed char (int)'{{$}} + // CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'signed char' static_cast<signed char> <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}} + return static_cast<signed char>(x); +} + +//----------------------------------------------------------------------------// + +using UnsignedChar = unsigned char; +using SignedChar = signed char; +using UnsignedInt = unsigned int; +using SignedInt = signed int; + +UnsignedChar cxxfunctionalcast_0(UnsignedInt x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_0 'UnsignedChar (UnsignedInt)'{{$}} + // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' functional cast to UnsignedChar <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' lvalue ParmVar {{.*}} 'x' 'UnsignedInt':'unsigned int'{{$}} + return UnsignedChar(x); +} + +SignedChar cxxfunctionalcast_1(UnsignedInt x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_1 'SignedChar (UnsignedInt)'{{$}} + // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' functional cast to SignedChar <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' lvalue ParmVar {{.*}} 'x' 'UnsignedInt':'unsigned int'{{$}} + return SignedChar(x); +} + +UnsignedChar cxxfunctionalcast_2(SignedInt x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_2 'UnsignedChar (SignedInt)'{{$}} + // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' functional cast to UnsignedChar <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' lvalue ParmVar {{.*}} 'x' 'SignedInt':'int'{{$}} + return UnsignedChar(x); +} + +SignedChar cxxfunctionalcast_3(SignedInt x) { + // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_3 'SignedChar (SignedInt)'{{$}} + // CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' functional cast to SignedChar <NoOp>{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' <IntegralCast> part_of_explicit_cast{{$}} + // CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' <LValueToRValue> part_of_explicit_cast{{$}} + // CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' lvalue ParmVar {{.*}} 'x' 'SignedInt':'int'{{$}} + return SignedChar(x); +} diff --git a/test/AST/objc-default-ctor-init.mm b/test/AST/objc-default-ctor-init.mm new file mode 100644 index 0000000000000..a14a243a31cca --- /dev/null +++ b/test/AST/objc-default-ctor-init.mm @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -std=c++11 -ast-dump %s | FileCheck %s
+// CHECK: CXXCtorInitializer Field {{.*}} 'ptr' 'void *'
+// CHECK: CXXCtorInitializer Field {{.*}} 'q' 'Q'
+
+@interface NSObject
+@end
+
+@interface I : NSObject
+@end
+
+struct Q { Q(); };
+
+struct S {
+ S();
+ void *ptr = nullptr;
+ Q q;
+};
+
+@implementation I
+S::S() {}
+@end
diff --git a/test/AST/pragma-attribute-cxx-subject-match-rules.cpp b/test/AST/pragma-attribute-cxx-subject-match-rules.cpp new file mode 100644 index 0000000000000..18dfb43a384d7 --- /dev/null +++ b/test/AST/pragma-attribute-cxx-subject-match-rules.cpp @@ -0,0 +1,169 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=namespace" %s | FileCheck --check-prefix=CHECK-NAMESPACE %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=type_alias" %s | FileCheck --check-prefix=CHECK-TYPE_ALIAS %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=enum" %s | FileCheck --check-prefix=CHECK-ENUM %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=enum_constant" %s | FileCheck --check-prefix=CHECK-ENUM_CONSTANT %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=record" %s | FileCheck --check-prefix=CHECK-RECORD %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=record(unless(is_union))" %s | FileCheck --check-prefix=CHECK-RECORD_UNLESS_IS_UNION %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=field" %s | FileCheck --check-prefix=CHECK-FIELD %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=function" %s | FileCheck --check-prefix=CHECK-FUNCTION %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=hasType(functionType)" %s | FileCheck --check-prefix=CHECK-HAS_TYPE_FUNCTION_TYPE %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=function(is_member)" %s | FileCheck --check-prefix=CHECK-FUNCTION_IS_MEMBER %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable" %s | FileCheck --check-prefix=CHECK-VARIABLE %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable(is_global)" %s | FileCheck --check-prefix=CHECK-VARIABLE_IS_GLOBAL %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable(is_parameter)" %s | FileCheck --check-prefix=CHECK-VARIABLE_IS_PARAMETER %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable(unless(is_parameter))" %s | FileCheck --check-prefix=CHECK-VARIABLE_UNLESS_IS_PARAMETER %s + +#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(SUBJECT)) + +namespace testNamespace { +// CHECK-NAMESPACE: NamespaceDecl{{.*}} testNamespace +// CHECK-NAMESPACE-NEXT: AnnotateAttr{{.*}} "test" + +typedef int testTypedef; +// CHECK-TYPE_ALIAS: TypedefDecl{{.*}} testTypedef +// CHECK-TYPE_ALIAS-NEXT: BuiltinType +// CHECK-TYPE_ALIAS-NEXT: AnnotateAttr{{.*}} "test" + +using testTypeAlias = double; +// CHECK-TYPE_ALIAS: TypeAliasDecl{{.*}} testTypeAlias +// CHECK-TYPE_ALIAS-NEXT: BuiltinType +// CHECK-TYPE_ALIAS-NEXT: AnnotateAttr{{.*}} "test" + +enum testEnum { + testEnumCase1, + testEnumCase2 +}; +// CHECK-ENUM: EnumDecl{{.*}} testEnum +// CHECK-ENUM-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-ENUM_CONSTANT: EnumConstantDecl{{.*}} testEnumCase1 +// CHECK-ENUM_CONSTANT-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-ENUM_CONSTANT: EnumConstantDecl{{.*}} testEnumCase2 +// CHECK-ENUM_CONSTANT-NEXT: AnnotateAttr{{.*}} "test" + +struct testStructRecord { + int testStructRecordField; +}; +// CHECK-RECORD: CXXRecordDecl{{.*}} testStructRecord +// CHECK-RECORD: AnnotateAttr{{.*}} "test" +// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testStructRecord +// CHECK-RECORD_UNLESS_IS_UNION: AnnotateAttr{{.*}} "test" +// CHECK-FIELD: FieldDecl{{.*}} testStructRecordField +// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test" + +class testClassRecord { + int testClassRecordField; +}; +// CHECK-RECORD: CXXRecordDecl{{.*}} testClassRecord +// CHECK-RECORD: AnnotateAttr{{.*}} "test" +// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testClassRecord +// CHECK-RECORD_UNLESS_IS_UNION: AnnotateAttr{{.*}} "test" +// CHECK-FIELD: FieldDecl{{.*}} testClassRecordField +// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test" + +union testUnionRecord { + int testUnionRecordField; +}; +// CHECK-RECORD: CXXRecordDecl{{.*}} testUnionRecord +// CHECK-RECORD: AnnotateAttr{{.*}} "test" +// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testUnionRecord +// CHECK-RECORD_UNLESS_IS_UNION-NOT: AnnotateAttr{{.*}} "test" +// CHECK-FIELD: FieldDecl{{.*}} testUnionRecordField +// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test" + +// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl +void testFunctionDecl(); +// CHECK-FUNCTION: FunctionDecl{{.*}} testFunctionDecl +// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE: FunctionDecl{{.*}} testFunctionDecl +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" + +void testFunctionDecl() { } +// CHECK-FUNCTION: FunctionDecl{{.*}} testFunctionDecl +// CHECK-FUNCTION-NEXT: CompoundStmt +// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE: FunctionDecl{{.*}} testFunctionDecl +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: CompoundStmt +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" + +void (*testFunctionVar)(); +// CHECK-HAS_TYPE_FUNCTION_TYPE: VarDecl{{.*}} testFunctionVar +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" +// 'function' should not apply to variables with a function type! +// CHECK-FUNCTION: VarDecl{{.*}} testFunctionVar +// CHECK-FUNCTION-NOT: AnnotateAttr{{.*}} "test" + +class testMethods { + testMethods(); + void testMethod(); +}; +void testMethods::testMethod() { } +void testFunctionNotMethod(); +// CHECK-FUNCTION-LABEL: CXXConstructorDecl{{.*}} testMethods +// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-FUNCTION_IS_MEMBER: CXXConstructorDecl{{.*}} testMethods +// CHECK-FUNCTION_IS_MEMBER-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE: CXXConstructorDecl{{.*}} testMethods +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-FUNCTION: CXXMethodDecl{{.*}} testMethod +// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-FUNCTION_IS_MEMBER: CXXMethodDecl{{.*}} testMethod +// CHECK-FUNCTION_IS_MEMBER-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE: CXXMethodDecl{{.*}} testMethod +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-FUNCTION: CXXMethodDecl{{.*}} testMethod +// CHECK-FUNCTION-NEXT: CompoundStmt +// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-FUNCTION_IS_MEMBER: CXXMethodDecl{{.*}} testMethod +// CHECK-FUNCTION_IS_MEMBER-NEXT: CompoundStmt +// CHECK-CXX_METHOD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE: CXXMethodDecl{{.*}} testMethod +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: CompoundStmt +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-FUNCTION_IS_MEMBER: FunctionDecl{{.*}} testFunctionNotMethod +// CHECK-FUNCTION_IS_MEMBER-NOT: AnnotateAttr{{.*}} "test" + +int testVariable; +// CHECK-VARIABLE: VarDecl{{.*}} testVariable +// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testVariable +// CHECK-VARIABLE_IS_GLOBAL-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testVariable +// CHECK-VARIABLE_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testVariable +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test" +void testVarFunction(int testParam) { +// CHECK-VARIABLE: VarDecl{{.*}} testParam +// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testParam +// CHECK-VARIABLE_IS_GLOBAL-NOT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testParam +// CHECK-VARIABLE_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testParam +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test" + + int testLocalVariable; +// CHECK-VARIABLE: VarDecl{{.*}} testLocalVariable +// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testLocalVariable +// CHECK-VARIABLE_IS_GLOBAL-NOT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testLocalVariable +// CHECK-VARIABLE_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testLocalVariable +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test" +} +class testVarClass { + static int testStaticVar; +}; +// CHECK-VARIABLE: VarDecl{{.*}} testStaticVar +// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testStaticVar +// CHECK-VARIABLE_IS_GLOBAL-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testStaticVar +// CHECK-VARIABLE_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test" +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testStaticVar +// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test" + + +} + +#pragma clang attribute pop diff --git a/test/AST/pragma-attribute-objc-subject-match-rules.m b/test/AST/pragma-attribute-objc-subject-match-rules.m new file mode 100644 index 0000000000000..09ab5e1f33a0d --- /dev/null +++ b/test/AST/pragma-attribute-objc-subject-match-rules.m @@ -0,0 +1,113 @@ +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump "-DSUBJECT=objc_interface" %s | FileCheck --check-prefix=CHECK-OBJC_INTERFACE %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_protocol" %s | FileCheck --check-prefix=CHECK-OBJC_PROTOCOL %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump "-DSUBJECT=objc_category" %s | FileCheck --check-prefix=CHECK-OBJC_CATEGORY %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_method" %s | FileCheck --check-prefix=CHECK-OBJC_METHOD %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_method(is_instance)" %s | FileCheck --check-prefix=CHECK-OBJC_METHOD_IS_INSTANCE %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=field" %s | FileCheck --check-prefix=CHECK-FIELD %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_property" %s | FileCheck --check-prefix=CHECK-OBJC_PROPERTY %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=block" %s | FileCheck --check-prefix=CHECK-BLOCK %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=hasType(functionType)" %s | FileCheck --check-prefix=CHECK-HAS_TYPE_FUNCTION_TYPE %s + +#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(SUBJECT)) + +@interface testInterface +@end +// CHECK-OBJC_INTERFACE: ObjCInterfaceDecl{{.*}} testInterface +// CHECK-OBJC_INTERFACE-NEXT: AnnotateAttr{{.*}} "test" + +@interface testInterface () +@end +// CHECK-OBJC_INTERFACE: ObjCCategoryDecl +// CHECK-OBJC_INTERFACE-NOT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_CATEGORY: ObjCCategoryDecl +// CHECK-OBJC_CATEGORY-NEXT: ObjCInterface +// CHECK-OBJC_CATEGORY-NEXT: AnnotateAttr{{.*}} "test" + +@interface testInterface (testCategory) +@end +// CHECK-OBJC_INTERFACE: ObjCCategoryDecl{{.*}} testCategory +// CHECK-OBJC_INTERFACE-NOT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_CATEGORY: ObjCCategoryDecl{{.*}} testCategory +// CHECK-OBJC_CATEGORY-NEXT: ObjCInterface +// CHECK-OBJC_CATEGORY-NEXT: AnnotateAttr{{.*}} "test" + +// CHECK-OBJC_INTERFACE-LABEL: ObjCProtocolDecl +@protocol testProtocol +@end +// CHECK-OBJC_PROTOCOL: ObjCProtocolDecl{{.*}} testProtocol +// CHECK-OBJC_PROTOCOL-NEXT: AnnotateAttr{{.*}} "test" + +@interface methodContainer +- (void) testInstanceMethod; ++ (void) testClassMethod; +@end +// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testInstanceMethod +// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testClassMethod +// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_METHOD_IS_INSTANCE: ObjCMethodDecl{{.*}} testInstanceMethod +// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_METHOD_IS_INSTANCE-LABEL: ObjCMethodDecl{{.*}} testClassMethod +// CHECK-OBJC_METHOD_IS_INSTANCE-NOT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testInstanceMethod +// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testClassMethod +// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test" + +@implementation methodContainer +- (void) testInstanceMethod { } ++ (void) testClassMethod { } +@end +// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testInstanceMethod +// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl +// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl +// CHECK-OBJC_METHOD-NEXT: CompoundStmt +// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testClassMethod +// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl +// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl +// CHECK-OBJC_METHOD-NEXT: CompoundStmt +// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_METHOD_IS_INSTANCE-LABEL: ObjCMethodDecl{{.*}} testInstanceMethod +// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: ImplicitParamDecl +// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: ImplicitParamDecl +// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: CompoundStmt +// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-OBJC_METHOD_IS_INSTANCE: ObjCMethodDecl{{.*}} testClassMethod +// CHECK-OBJC_METHOD_IS_INSTANCE-NOT: AnnotateAttr{{.*}} "test" + +// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testInstanceMethod +// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testClassMethod +// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test" +@interface propertyContainer { + int testIvar; +// CHECK-FIELD: ObjCIvarDecl{{.*}} testIvar +// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test" + +} +@property int testProperty; +// CHECK-OBJC_PROPERTY: ObjCPropertyDecl{{.*}} testProperty +// CHECK-OBJC_PROPERTY-NEXT: AnnotateAttr{{.*}} "test" + +@end + +void (^testBlockVar)(); +// CHECK-BLOCK: VarDecl{{.*}} testBlockVar +// CHECK-BLOCK-NOT: AnnotateAttr{{.*}} "test" + +void testBlock() { + (void)(^ { }); +} +// CHECK-BLOCK-LABEL: BlockDecl +// CHECK-BLOCK-NEXT: CompoundStmt +// CHECK-BLOCK-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: FunctionDecl{{.*}} testBlock +// CHECK-HAS_TYPE_FUNCTION_TYPE: BlockDecl +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: CompoundStmt +// The attribute applies to function, but not to block: +// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test" + + +#pragma clang attribute pop diff --git a/test/AST/property-atomic-bool.m b/test/AST/property-atomic-bool.m new file mode 100644 index 0000000000000..4110b5e044590 --- /dev/null +++ b/test/AST/property-atomic-bool.m @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -ast-dump "%s" | FileCheck %s + +// CHECK: TypedefDecl {{.*}} referenced AtomicBool '_Atomic(_Bool)' +// CHECK: AtomicType {{.*}} '_Atomic(_Bool)' +// CHECK: BuiltinType {{.*}} '_Bool' +// CHECK: ObjCInterfaceDecl {{.*}} A0 +// CHECK: ObjCPropertyDecl {{.*}} p '_Atomic(_Bool)' {{.*}} nonatomic +// CHECK: ObjCMethodDecl {{.*}} implicit - p '_Bool' +// CHECK: ObjCMethodDecl {{.*}} implicit - setP: 'void' +// CHECK: ParmVarDecl {{.*}} p '_Bool' +// CHECK: ObjCInterfaceDecl {{.*}} A1 +// CHECK: ObjCPropertyDecl {{.*}} p 'AtomicBool':'_Atomic(_Bool)' {{.*}} nonatomic +// CHECK: ObjCMethodDecl {{.*}} implicit - p '_Bool' +// CHECK: ObjCMethodDecl {{.*}} implicit - setP: 'void' +// CHECK: ParmVarDecl {{.*}} p '_Bool' +// CHECK: ObjCInterfaceDecl {{.*}} A2 +// CHECK: ObjCIvarDecl {{.*}} p '_Atomic(_Bool)' protected +// CHECK: ObjCPropertyDecl {{.*}} p '_Atomic(_Bool)' +// CHECK: ObjCMethodDecl {{.*}} implicit - p '_Bool' +// CHECK: ObjCMethodDecl {{.*}} implicit - setP: 'void' +// CHECK: ParmVarDecl {{.*}} p '_Bool' +// CHECK: ObjCInterfaceDecl {{.*}} A3 +// CHECK: ObjCIvarDecl {{.*}} p 'AtomicBool':'_Atomic(_Bool)' protected +// CHECK: ObjCPropertyDecl {{.*}} p 'AtomicBool':'_Atomic(_Bool)' +// CHECK: ObjCMethodDecl {{.*}} implicit - p '_Bool' +// CHECK: ObjCMethodDecl {{.*}} implicit - setP: 'void' +// CHECK: ParmVarDecl {{.*}} p '_Bool' + +typedef _Atomic(_Bool) AtomicBool; + +@interface A0 +@property(nonatomic) _Atomic(_Bool) p; +@end +@implementation A0 +@end + +@interface A1 +@property(nonatomic) AtomicBool p; +@end +@implementation A1 +@end + +@interface A2 { + _Atomic(_Bool) p; +} +@property _Atomic(_Bool) p; +@end + +@implementation A2 +@synthesize p; +@end + +@interface A3 { + AtomicBool p; +} +@property AtomicBool p; +@end + +@implementation A3 +@synthesize p; +@end diff --git a/test/AST/rdr6094103-unordered-compare-promote.c b/test/AST/rdr6094103-unordered-compare-promote.c new file mode 100644 index 0000000000000..7bb363e797c86 --- /dev/null +++ b/test/AST/rdr6094103-unordered-compare-promote.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -ast-dump %s 2>&1 | grep ImplicitCastExpr | count 4 + +int foo (double x, long double y) { + // There needs to be an implicit cast on x here. + return __builtin_isgreater(x, y); +} diff --git a/test/AST/sourceranges.cpp b/test/AST/sourceranges.cpp new file mode 100644 index 0000000000000..53f2f57e67545 --- /dev/null +++ b/test/AST/sourceranges.cpp @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -triple i686-mingw32 -ast-dump %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-mingw32 -std=c++1z -ast-dump %s | FileCheck %s -check-prefix=CHECK-1Z
+
+template<class T>
+class P {
+ public:
+ P(T* t) {}
+};
+
+namespace foo {
+class A { public: A(int = 0) {} };
+enum B {};
+typedef int C;
+}
+
+// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:[[@LINE+1]]:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
+static foo::A ImplicitConstrArray[2];
+
+int main() {
+ // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::A *'
+ P<foo::A> p14 = new foo::A;
+ // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::B *'
+ P<foo::B> p24 = new foo::B;
+ // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::C *'
+ P<foo::C> pr4 = new foo::C;
+}
+
+foo::A getName() {
+ // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
+ return foo::A();
+}
+
+void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
+ a1->~A();
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
+ a2->foo::A::~A();
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
+ p1->~P<int>();
+}
+
+struct D {
+ D(int);
+ ~D();
+};
+
+void construct() {
+ using namespace foo;
+ A a = A(12);
+ // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'foo::A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
+ D d = D(12);
+ // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'D' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
+}
+
+namespace PR38987 {
+struct A { A(); };
+template <class T> void f() { T{}; }
+template void f<A>();
+// CHECK: CXXTemporaryObjectExpr {{.*}} <col:31, col:33> 'PR38987::A':'PR38987::A'
+}
+
+void abort() __attribute__((noreturn));
+
+namespace std {
+typedef decltype(sizeof(int)) size_t;
+
+template <typename E> struct initializer_list {
+ const E *p;
+ size_t n;
+ initializer_list(const E *p, size_t n) : p(p), n(n) {}
+};
+
+template <typename F, typename S> struct pair {
+ F f;
+ S s;
+ pair(const F &f, const S &s) : f(f), s(s) {}
+};
+
+struct string {
+ const char *str;
+ string() { abort(); }
+ string(const char *S) : str(S) {}
+ ~string() { abort(); }
+};
+
+template<typename K, typename V>
+struct map {
+ using T = pair<K, V>;
+ map(initializer_list<T> i, const string &s = string()) {}
+ ~map() { abort(); }
+};
+
+}; // namespace std
+
+#if __cplusplus >= 201703L
+// CHECK-1Z: FunctionDecl {{.*}} construct_with_init_list
+std::map<int, int> construct_with_init_list() {
+ // CHECK-1Z-NEXT: CompoundStmt
+ // CHECK-1Z-NEXT: ReturnStmt {{.*}} <line:[[@LINE+5]]:3, col:35
+ // CHECK-1Z-NEXT: ExprWithCleanups {{.*}} <col:10, col:35
+ // CHECK-1Z-NEXT: CXXBindTemporaryExpr {{.*}} <col:10, col:35
+ // CHECK-1Z-NEXT: CXXTemporaryObjectExpr {{.*}} <col:10, col:35
+ // CHECK-1Z-NEXT: CXXStdInitializerListExpr {{.*}} <col:28, col:35
+ return std::map<int, int>{{0, 0}};
+}
+
+// CHECK-1Z: NamespaceDecl {{.*}} in_class_init
+namespace in_class_init {
+ struct A {};
+
+ // CHECK-1Z: CXXRecordDecl {{.*}} struct B definition
+ struct B {
+ // CHECK-1Z: FieldDecl {{.*}} a 'in_class_init::A'
+ // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:11, col:12
+ A a = {};
+ };
+}
+
+// CHECK-1Z: NamespaceDecl {{.*}} delegating_constructor_init
+namespace delegating_constructor_init {
+ struct A {};
+
+ struct B : A {
+ A a;
+ B(A a) : a(a) {}
+ };
+
+ // CHECK-1Z: CXXRecordDecl {{.*}} struct C definition
+ struct C : B {
+ // CHECK-1Z: CXXConstructorDecl {{.*}} C
+ // CHECK-1Z-NEXT: CXXCtorInitializer 'delegating_constructor_init::B'
+ // CHECK-1Z-NEXT: CXXConstructExpr {{.*}} <col:11, col:15
+ // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:13, col:14
+ C() : B({}) {};
+ };
+}
+
+// CHECK-1Z: NamespaceDecl {{.*}} new_init
+namespace new_init {
+ void A() {
+ // CHECK-1Z: CXXNewExpr {{.*}} <line:[[@LINE+2]]:5, col:14
+ // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:12, col:14
+ new int{0};
+ }
+}
+#endif
diff --git a/test/AST/template-implicit-vars.cpp b/test/AST/template-implicit-vars.cpp new file mode 100644 index 0000000000000..25d35fbdb84f5 --- /dev/null +++ b/test/AST/template-implicit-vars.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump | FileCheck %s +template<typename T> +void f(T t) { + T a[] = {t}; + for (auto x : a) {} +} + +void g() { + f(1); +} +// CHECK: VarDecl {{.*}} implicit used __range +// CHECK: VarDecl {{.*}} implicit used __range +// CHECK: VarDecl {{.*}} implicit used __begin +// CHECK: VarDecl {{.*}} implicit used __end diff --git a/test/AST/variadic-promotion.c b/test/AST/variadic-promotion.c new file mode 100644 index 0000000000000..01d8e934b4eb1 --- /dev/null +++ b/test/AST/variadic-promotion.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -ast-dump %s | FileCheck %s + +void variadic(int, ...); + +void test_floating_promotion(__fp16 *f16, float f32, double f64) { + variadic(3, *f16, f32, f64); + +// CHECK: ImplicitCastExpr {{.*}} 'double' <FloatingCast> +// CHECK-NEXT: '__fp16' + +// CHECK: ImplicitCastExpr {{.*}} 'double' <FloatingCast> +// CHECK-NEXT: 'float' +} |