summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRenato Golin <renato.golin@linaro.org>2014-05-19 18:15:42 +0000
committerRenato Golin <renato.golin@linaro.org>2014-05-19 18:15:42 +0000
commit230c5eb4bde7314331ae5c0bca65087ed504202c (patch)
tree4e74f0d0624a6e259fefce46c6d6c1898b982124 /clang/lib/Sema/SemaDecl.cpp
parent194cfa9b21ef52bb855afab36553daad0ecd7681 (diff)
downloadbcm5719-llvm-230c5eb4bde7314331ae5c0bca65087ed504202c.tar.gz
bcm5719-llvm-230c5eb4bde7314331ae5c0bca65087ed504202c.zip
Non-allocatable Global Named Register
This patch implements global named registers in Clang, lowering to the just created intrinsics in LLVM (@llvm.read/write_register). A new type of LValue had to be created (Register), which just adds support to carry the metadata node containing the name of the register. Two new methods to emit loads and stores interoperate with another to emit the named metadata node. No guarantees are being made and only non-allocatable global variable named registers are being supported. Local named register support is unchanged. llvm-svn: 209149
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp15
1 files changed, 8 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3c19e9632f6..5276cafcf72 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5119,13 +5119,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!DC->isRecord() && S->getFnParent() == 0) {
// C99 6.9p2: The storage-class specifiers auto and register shall not
// appear in the declaration specifiers in an external declaration.
- if (SC == SC_Auto || SC == SC_Register) {
- // If this is a register variable with an asm label specified, then this
- // is a GNU extension.
- if (SC == SC_Register && D.getAsmLabel())
- Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
- else
- Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
+ // Global Register+Asm is a GNU extension we support.
+ if (SC == SC_Auto || (SC == SC_Register && !D.getAsmLabel())) {
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
D.setInvalidType();
}
}
@@ -5437,6 +5433,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
break;
case SC_Register:
+ // Local Named register
if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
break;
@@ -5446,6 +5443,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
case SC_OpenCLWorkGroupLocal:
break;
}
+ } else if (SC == SC_Register) {
+ // Global Named register
+ if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
}
NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
OpenPOWER on IntegriCloud