aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-05-06 23:10:14 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-05-06 23:10:14 -0700
commitc098a8f5223855b410895b5396948e3e2b3aacba (patch)
treeac3c4e5fa9de71a1b703d52433e0e1cec3abe7cf /src/analyze.cpp
parent271a37b418828c8ee79402f97016be42c5fa2884 (diff)
downloadzig-c098a8f5223855b410895b5396948e3e2b3aacba.tar.gz
zig-c098a8f5223855b410895b5396948e3e2b3aacba.zip
add frame_address and return_address builtins
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 4d1dc181a0..928f576947 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -980,6 +980,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
bool is_cold = false;
bool is_naked = false;
bool is_test = false;
+ bool is_noinline = false;
if (fn_proto->top_level_decl.directives) {
for (int i = 0; i < fn_proto->top_level_decl.directives->length; i += 1) {
@@ -993,6 +994,8 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
if (attr_name) {
if (buf_eql_str(attr_name, "naked")) {
is_naked = true;
+ } else if (buf_eql_str(attr_name, "noinline")) {
+ is_noinline = true;
} else if (buf_eql_str(attr_name, "cold")) {
is_cold = true;
} else if (buf_eql_str(attr_name, "test")) {
@@ -1062,12 +1065,20 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
fn_table_entry->type_entry = fn_type;
fn_table_entry->is_test = is_test;
+ fn_table_entry->is_noinline = is_noinline;
if (fn_type->id == TypeTableEntryIdInvalid) {
fn_proto->skip = true;
return;
}
+ if (fn_table_entry->is_inline && fn_table_entry->is_noinline) {
+ add_node_error(g, node, buf_sprintf("function is both inline and noinline"));
+ fn_proto->skip = true;
+ return;
+ }
+
+
Buf *symbol_name;
if (is_c_compat) {
symbol_name = &fn_table_entry->symbol_name;
@@ -1081,6 +1092,9 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
if (fn_table_entry->is_inline) {
LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMAlwaysInlineAttribute);
}
+ if (fn_table_entry->is_noinline) {
+ LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNoInlineAttribute);
+ }
if (fn_type->data.fn.fn_type_id.is_naked) {
LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNakedAttribute);
}
@@ -4866,6 +4880,10 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
case BuiltinFnIdBreakpoint:
mark_impure_fn(context);
return g->builtin_types.entry_void;
+ case BuiltinFnIdReturnAddress:
+ case BuiltinFnIdFrameAddress:
+ mark_impure_fn(context);
+ return builtin_fn->return_type;
case BuiltinFnIdEmbedFile:
return analyze_embed_file(g, import, context, node);
case BuiltinFnIdCmpExchange: