262 lines
9.3 KiB
C++
262 lines
9.3 KiB
C++
// 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
|