// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-pc-linux-gnu -emit-llvm %s -o - -verify | FileCheck %s
// CHECK: @weakvar = weak{{.*}} global
// CHECK: @__weakvar_alias ={{.*}} global
// CHECK: @correct_linkage = weak{{.*}} global
// CHECK-DAG: @both ={{.*}} alias void (), void ()* @__both
// CHECK-DAG: @both2 ={{.*}} alias void (), void ()* @__both2
// CHECK-DAG: @weakvar_alias = weak{{.*}} alias i32, i32* @__weakvar_alias
// CHECK-DAG: @foo = weak{{.*}} alias void (), void ()* @__foo
// CHECK-DAG: @foo2 = weak{{.*}} alias void (), void ()* @__foo2
// CHECK-DAG: @stutter = weak{{.*}} alias void (), void ()* @__stutter
// CHECK-DAG: @stutter2 = weak{{.*}} alias void (), void ()* @__stutter2
// CHECK-DAG: @declfirst = weak{{.*}} alias void (), void ()* @__declfirst
// CHECK-DAG: @declfirstattr = weak{{.*}} alias void (), void ()* @__declfirstattr
// CHECK-DAG: @mix2 = weak{{.*}} alias void (), void ()* @__mix2
// CHECK-DAG: @a1 = weak{{.*}} alias void (), void ()* @__a1
// CHECK-DAG: @xxx = weak{{.*}} alias void (), void ()* @__xxx
// CHECK-DAG: @undecfunc_alias1 = weak{{.*}} alias void (), void ()* @undecfunc
// CHECK-DAG: @undecfunc_alias2 = weak{{.*}} alias void (), void ()* @undecfunc
// CHECK-DAG: @undecfunc_alias3 = weak{{.*}} alias void (), void ()* @undecfunc
// CHECK-DAG: @undecfunc_alias4 = weak{{.*}} alias void (), void ()* @undecfunc
// CHECK-LABEL: define weak{{.*}} void @weakdef()
int weakvar;
void
void
int __weakvar_alias;
void
// CHECK-LABEL: define{{.*}} void @__foo()
void
// CHECK-LABEL: define{{.*}} void @__foo2()
///// test errors
typedef int td;
typedef int __td2;
typedef int __td3;
///// test weird cases
// test repeats
void
// CHECK-LABEL: define{{.*}} void @__stutter()
void
// CHECK-LABEL: define{{.*}} void @__stutter2()
// test decl/pragma weak order
void ;
void
// CHECK-LABEL: define{{.*}} void @__declfirst()
void ;
void
// CHECK-LABEL: define{{.*}} void @__declfirstattr()
//// test that other attributes are preserved
//// ensure that pragma weak/__attribute((weak)) play nice
void ;
void
// CHECK-LABEL: define weak{{.*}} void @mix()
// ensure following __attributes are preserved and that only a single
// alias is generated
void ;
void ;
void
// CHECK-LABEL: define{{.*}} void @__mix2()
////////////// test #pragma weak/__attribute combinations
// if the SAME ALIAS is already declared then it overrides #pragma weak
// resulting in a non-weak alias in this case
void ;
void
// CHECK-LABEL: define{{.*}} void @__both()
// if the TARGET is previously declared then whichever aliasing method
// comes first applies and subsequent aliases are discarded.
// TODO: warn about this
void ;
void ; // first, wins
void
// CHECK-LABEL: define{{.*}} void @__both2()
///////////// ensure that #pragma weak does not alter existing __attributes()
void ;
void
// CHECK: define{{.*}} void @__a1() [[NI:#[0-9]+]]
void
// CHECK: void @__xxx() [[RN:#[0-9]+]]
///////////// PR28611: Try multiple aliases of same undeclared symbol or alias
void ;
void
///////////// PR10878: Make sure we can call a weak alias
void
void
// CHECK: call void @SHA384Pad(i8* noundef null)
// PR14046: Parse #pragma weak in function-local context
extern int ;
void
// CHECK: declare extern_weak i32 @PR14046e()
// Parse #pragma weak after a label or case statement
extern int ;
extern int ;
extern int ;
void
// CHECK: declare extern_weak i32 @PR16705a()
// CHECK: declare extern_weak i32 @PR16705b()
// CHECK: declare extern_weak i32 @PR16705c()
///////////// TODO: stuff that still doesn't work
// due to the fact that disparate TopLevelDecls cannot affect each other
// (due to clang's Parser and ASTConsumer behavior, and quite reasonable)
// #pragma weak must appear before or within the same TopLevelDecl as it
// references.
void
void
// NOTE: weak doesn't apply, not before or in same TopLevelDec(!)
// CHECK-LABEL: define{{.*}} void @yyy()
int correct_linkage;
// CHECK: attributes [[NI]] = { noinline nounwind{{.*}} }
// CHECK: attributes [[RN]] = { noinline nounwind optnone readnone{{.*}} }