r281298 - Allow register variables in naked functions.

2016-09-13 Thread Nikola Smiljanic via cfe-commits
Author: nikola
Date: Tue Sep 13 02:02:02 2016
New Revision: 281298

URL: http://llvm.org/viewvc/llvm-project?rev=281298&view=rev
Log:
Allow register variables in naked functions.

Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Sema/attr-naked.c

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=281298&r1=281297&r2=281298&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Sep 13 02:02:02 2016
@@ -11818,6 +11818,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
 
 if (FD && FD->hasAttr()) {
   for (const Stmt *S : Body->children()) {
+// Allow local register variables without initializer as they don't
+// require prologue.
+bool RegisterVariables = false;
+if (auto *DS = dyn_cast(S)) {
+  for (const auto *Decl : DS->decls()) {
+if (const auto *Var = dyn_cast(Decl)) {
+  RegisterVariables =
+  Var->hasAttr() && !Var->hasInit();
+  if (!RegisterVariables)
+break;
+}
+  }
+}
+if (RegisterVariables)
+  continue;
 if (!isa(S) && !isa(S)) {
   Diag(S->getLocStart(), diag::err_non_asm_stmt_in_naked_function);
   Diag(FD->getAttr()->getLocation(), diag::note_attribute);

Modified: cfe/trunk/test/Sema/attr-naked.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-naked.c?rev=281298&r1=281297&r2=281298&view=diff
==
--- cfe/trunk/test/Sema/attr-naked.c (original)
+++ cfe/trunk/test/Sema/attr-naked.c Tue Sep 13 02:02:02 2016
@@ -48,3 +48,21 @@ __attribute__((naked)) void t9(int z) {
"r"(z) // expected-error{{parameter references not allowed in 
naked functions}}
);
 }
+
+__attribute__((naked)) void t10() {  // expected-note{{attribute is here}}
+  int a; // expected-error{{non-ASM statement in naked function is not 
supported}}
+}
+
+__attribute__((naked)) void t11() {  // expected-note{{attribute is here}}
+  register int a asm("eax") = x; // expected-error{{non-ASM statement in naked 
function is not supported}}
+}
+
+__attribute__((naked)) void t12() {  // expected-note{{attribute is here}}
+  register int a asm("eax"), b asm("ebx") = x; // expected-error{{non-ASM 
statement in naked function is not supported}}
+}
+
+__attribute__((naked)) void t13() {
+  register int a asm("eax");
+  register int b asm("ebx"), c asm("ecx");
+}
+


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r298574 - Fix issues in clang-format's AlignConsecutive modes.

2017-03-22 Thread Nikola Smiljanic via cfe-commits
Author: nikola
Date: Wed Mar 22 21:51:25 2017
New Revision: 298574

URL: http://llvm.org/viewvc/llvm-project?rev=298574&view=rev
Log:
Fix issues in clang-format's AlignConsecutive modes.

Patch by Ben Harper.

Modified:
cfe/trunk/lib/Format/WhitespaceManager.cpp
cfe/trunk/lib/Format/WhitespaceManager.h
cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/WhitespaceManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.cpp?rev=298574&r1=298573&r2=298574&view=diff
==
--- cfe/trunk/lib/Format/WhitespaceManager.cpp (original)
+++ cfe/trunk/lib/Format/WhitespaceManager.cpp Wed Mar 22 21:51:25 2017
@@ -50,9 +50,9 @@ void WhitespaceManager::replaceWhitespac
   if (Tok.Finalized)
 return;
   Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue;
-  Changes.push_back(Change(Tok, /*CreateReplacement=*/true,
-   Tok.WhitespaceRange, Spaces, StartOfTokenColumn,
-   Newlines, "", "", InPPDirective && !Tok.IsFirst,
+  Changes.push_back(Change(Tok, /*CreateReplacement=*/true, 
Tok.WhitespaceRange,
+   Spaces, StartOfTokenColumn, Newlines, "", "",
+   InPPDirective && !Tok.IsFirst,
/*IsInsideToken=*/false));
 }
 
@@ -192,21 +192,56 @@ AlignTokenSequence(unsigned Start, unsig
SmallVector &Changes) {
   bool FoundMatchOnLine = false;
   int Shift = 0;
+
+  // ScopeStack keeps track of the current scope depth. It contains indices of
+  // the first token on each scope.
+  // We only run the "Matches" function on tokens from the outer-most scope.
+  // However, we do need to pay special attention to one class of tokens
+  // that are not in the outer-most scope, and that is function parameters
+  // which are split across multiple lines, as illustrated by this example:
+  //   double a(int x);
+  //   intb(int  y,
+  //  double z);
+  // In the above example, we need to take special care to ensure that
+  // 'double z' is indented along with it's owning function 'b'.
+  SmallVector ScopeStack;
+
   for (unsigned i = Start; i != End; ++i) {
-if (Changes[i].NewlinesBefore > 0) {
-  FoundMatchOnLine = false;
+if (ScopeStack.size() != 0 &&
+Changes[i].nestingAndIndentLevel() <
+Changes[ScopeStack.back()].nestingAndIndentLevel())
+  ScopeStack.pop_back();
+
+if (i != Start && Changes[i].nestingAndIndentLevel() >
+  Changes[i - 1].nestingAndIndentLevel())
+  ScopeStack.push_back(i);
+
+bool InsideNestedScope = ScopeStack.size() != 0;
+
+if (Changes[i].NewlinesBefore > 0 && !InsideNestedScope) {
   Shift = 0;
+  FoundMatchOnLine = false;
 }
 
 // If this is the first matching token to be aligned, remember by how many
 // spaces it has to be shifted, so the rest of the changes on the line are
 // shifted by the same amount
-if (!FoundMatchOnLine && Matches(Changes[i])) {
+if (!FoundMatchOnLine && !InsideNestedScope && Matches(Changes[i])) {
   FoundMatchOnLine = true;
   Shift = Column - Changes[i].StartOfTokenColumn;
   Changes[i].Spaces += Shift;
 }
 
+// This is for function parameters that are split across multiple lines,
+// as mentioned in the ScopeStack comment.
+if (InsideNestedScope && Changes[i].NewlinesBefore > 0) {
+  unsigned ScopeStart = ScopeStack.back();
+  if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName) ||
+  (ScopeStart > Start + 1 &&
+   Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)))
+Changes[i].Spaces += Shift;
+}
+
 assert(Shift >= 0);
 Changes[i].StartOfTokenColumn += Shift;
 if (i + 1 != Changes.size())
@@ -214,15 +249,37 @@ AlignTokenSequence(unsigned Start, unsig
   }
 }
 
-// Walk through all of the changes and find sequences of matching tokens to
-// align. To do so, keep track of the lines and whether or not a matching token
-// was found on a line. If a matching token is found, extend the current
-// sequence. If the current line cannot be part of a sequence, e.g. because
-// there is an empty line before it or it contains only non-matching tokens,
-// finalize the previous sequence.
+// Walk through a subset of the changes, starting at StartAt, and find
+// sequences of matching tokens to align. To do so, keep track of the lines and
+// whether or not a matching token was found on a line. If a matching token is
+// found, extend the current sequence. If the current line cannot be part of a
+// sequence, e.g. because there is an empty line before it or it contains only
+// non-matching tokens, finalize the previous sequence.
+// The value returned is the token on which we stopped, either because we
+// exhausted all items inside Changes, or because we hit a scope level higher
+// than our ini