| // Test without serialization: |
| // RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s \ |
| // RUN: | FileCheck --strict-whitespace %s |
| // |
| // Test with serialization: |
| // RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -Wno-deprecated-declarations -emit-pch -o %t %s |
| // RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux -std=c++11 -Wno-deprecated-declarations \ |
| // RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ |
| // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \ |
| // RUN: | 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: value: Int 4 |
| // 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: BuiltinAttr{{.*}}Implicit |
| // 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); |
| } |
| } |
| } |
| |
| namespace TestLifetimeCategories { |
| class [[gsl::Owner(int)]] AOwner{}; |
| // CHECK: CXXRecordDecl{{.*}} class AOwner |
| // CHECK: OwnerAttr {{.*}} int |
| class [[gsl::Pointer(int)]] APointer{}; |
| // CHECK: CXXRecordDecl{{.*}} class APointer |
| // CHECK: PointerAttr {{.*}} int |
| |
| class [[gsl::Pointer]] PointerWithoutArgument{}; |
| // CHECK: CXXRecordDecl{{.*}} class PointerWithoutArgument |
| // CHECK: PointerAttr |
| |
| class [[gsl::Owner]] OwnerWithoutArgument{}; |
| // CHECK: CXXRecordDecl{{.*}} class OwnerWithoutArgument |
| // CHECK: OwnerAttr |
| } // namespace TestLifetimeCategories |
| |
| // 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 |