Basic support for formatting asm() statments.
llvm-svn: 177073
This commit is contained in:
parent
a097f7b1e3
commit
40aacf4872
|
@ -553,8 +553,6 @@ private:
|
|||
|
||||
State.Stack.back().LastSpace = State.Column;
|
||||
State.StartOfLineLevel = State.ParenLevel;
|
||||
if (Current.is(tok::colon) && Current.Type != TT_ConditionalExpr)
|
||||
State.Stack.back().Indent += 2;
|
||||
|
||||
// Any break on this level means that the parent level has been broken
|
||||
// and we need to avoid bin packing there.
|
||||
|
@ -1000,6 +998,8 @@ private:
|
|||
(State.NextToken->Parent->ClosesTemplateDeclaration &&
|
||||
State.ParenLevel == 0)))
|
||||
return true;
|
||||
if (State.NextToken->Type == TT_InlineASMColon)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,14 +92,14 @@ public:
|
|||
IdentifierInfo &Ident_in)
|
||||
: SourceMgr(SourceMgr), Lex(Lex), Line(Line), CurrentToken(&Line.First),
|
||||
KeywordVirtualFound(false), Ident_in(Ident_in) {
|
||||
Contexts.push_back(Context(1, /*IsExpression=*/ false));
|
||||
Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/ false));
|
||||
}
|
||||
|
||||
private:
|
||||
bool parseAngle() {
|
||||
if (CurrentToken == NULL)
|
||||
return false;
|
||||
ScopedContextCreator ContextCreator(*this, 10);
|
||||
ScopedContextCreator ContextCreator(*this, tok::less, 10);
|
||||
AnnotatedToken *Left = CurrentToken->Parent;
|
||||
Contexts.back().IsExpression = false;
|
||||
while (CurrentToken != NULL) {
|
||||
|
@ -124,7 +124,7 @@ private:
|
|||
bool parseParens(bool LookForDecls = false) {
|
||||
if (CurrentToken == NULL)
|
||||
return false;
|
||||
ScopedContextCreator ContextCreator(*this, 1);
|
||||
ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
|
||||
|
||||
// FIXME: This is a bit of a hack. Do better.
|
||||
Contexts.back().ColonIsForRangeExpr =
|
||||
|
@ -205,7 +205,7 @@ private:
|
|||
Parent->Type == TT_CastRParen ||
|
||||
getBinOpPrecedence(Parent->FormatTok.Tok.getKind(), true, true) >
|
||||
prec::Unknown);
|
||||
ScopedContextCreator ContextCreator(*this, 10);
|
||||
ScopedContextCreator ContextCreator(*this, tok::l_square, 10);
|
||||
Contexts.back().IsExpression = true;
|
||||
bool StartsObjCArrayLiteral = Parent && Parent->is(tok::at);
|
||||
|
||||
|
@ -256,7 +256,7 @@ private:
|
|||
// Lines are fine to end with '{'.
|
||||
if (CurrentToken == NULL)
|
||||
return true;
|
||||
ScopedContextCreator ContextCreator(*this, 1);
|
||||
ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
|
||||
AnnotatedToken *Left = CurrentToken->Parent;
|
||||
while (CurrentToken != NULL) {
|
||||
if (CurrentToken->is(tok::r_brace)) {
|
||||
|
@ -320,7 +320,7 @@ private:
|
|||
break;
|
||||
case tok::colon:
|
||||
// Colons from ?: are handled in parseConditional().
|
||||
if (Tok->Parent->is(tok::r_paren)) {
|
||||
if (Tok->Parent->is(tok::r_paren) && Contexts.size() == 1) {
|
||||
Tok->Type = TT_CtorInitializerColon;
|
||||
} else if (Contexts.back().ColonIsObjCMethodExpr ||
|
||||
Line.First.Type == TT_ObjCMethodSpecifier) {
|
||||
|
@ -336,6 +336,8 @@ private:
|
|||
Tok->Type = TT_RangeBasedForLoopColon;
|
||||
} else if (Contexts.size() == 1) {
|
||||
Tok->Type = TT_InheritanceColon;
|
||||
} else if (Contexts.back().ContextKind == tok::l_paren) {
|
||||
Tok->Type = TT_InlineASMColon;
|
||||
}
|
||||
break;
|
||||
case tok::kw_if:
|
||||
|
@ -531,12 +533,14 @@ private:
|
|||
/// \brief A struct to hold information valid in a specific context, e.g.
|
||||
/// a pair of parenthesis.
|
||||
struct Context {
|
||||
Context(unsigned BindingStrength, bool IsExpression)
|
||||
: BindingStrength(BindingStrength), LongestObjCSelectorName(0),
|
||||
ColonIsForRangeExpr(false), ColonIsObjCMethodExpr(false),
|
||||
FirstObjCSelectorName(NULL), IsExpression(IsExpression),
|
||||
CanBeExpression(true) {}
|
||||
Context(tok::TokenKind ContextKind, unsigned BindingStrength,
|
||||
bool IsExpression)
|
||||
: ContextKind(ContextKind), BindingStrength(BindingStrength),
|
||||
LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
|
||||
ColonIsObjCMethodExpr(false), FirstObjCSelectorName(NULL),
|
||||
IsExpression(IsExpression), CanBeExpression(true) {}
|
||||
|
||||
tok::TokenKind ContextKind;
|
||||
unsigned BindingStrength;
|
||||
unsigned LongestObjCSelectorName;
|
||||
bool ColonIsForRangeExpr;
|
||||
|
@ -551,9 +555,12 @@ private:
|
|||
struct ScopedContextCreator {
|
||||
AnnotatingParser &P;
|
||||
|
||||
ScopedContextCreator(AnnotatingParser &P, unsigned Increase) : P(P) {
|
||||
P.Contexts.push_back(Context(P.Contexts.back().BindingStrength + Increase,
|
||||
P.Contexts.back().IsExpression));
|
||||
ScopedContextCreator(AnnotatingParser &P, tok::TokenKind ContextKind,
|
||||
unsigned Increase)
|
||||
: P(P) {
|
||||
P.Contexts.push_back(
|
||||
Context(ContextKind, P.Contexts.back().BindingStrength + Increase,
|
||||
P.Contexts.back().IsExpression));
|
||||
}
|
||||
|
||||
~ScopedContextCreator() { P.Contexts.pop_back(); }
|
||||
|
@ -755,7 +762,8 @@ public:
|
|||
if (Current) {
|
||||
if (Current->Type == TT_ConditionalExpr)
|
||||
CurrentPrecedence = 1 + (int) prec::Conditional;
|
||||
else if (Current->is(tok::semi))
|
||||
else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon ||
|
||||
Current->Type == TT_CtorInitializerColon)
|
||||
CurrentPrecedence = 1;
|
||||
else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma))
|
||||
CurrentPrecedence = 1 + (int) getPrecedence(*Current);
|
||||
|
|
|
@ -34,6 +34,7 @@ enum TokenType {
|
|||
TT_ConditionalExpr,
|
||||
TT_CtorInitializerColon,
|
||||
TT_ImplicitStringLiteral,
|
||||
TT_InlineASMColon,
|
||||
TT_InheritanceColon,
|
||||
TT_LineComment,
|
||||
TT_ObjCArrayLiteral,
|
||||
|
|
|
@ -776,6 +776,16 @@ TEST_F(FormatTest, FormatsNamespaces) {
|
|||
|
||||
TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); }
|
||||
|
||||
TEST_F(FormatTest, FormatsInlineASM) {
|
||||
verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
|
||||
verifyFormat(
|
||||
"asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n"
|
||||
" \"cpuid\\n\\t\"\n"
|
||||
" \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n"
|
||||
" : \"=a\" (*rEAX), \"=S\" (*rEBX), \"=c\" (*rECX), \"=d\" (*rEDX)\n"
|
||||
" : \"a\"(value));");
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, FormatTryCatch) {
|
||||
// FIXME: Handle try-catch explicitly in the UnwrappedLineParser, then we'll
|
||||
// also not create single-line-blocks.
|
||||
|
|
Loading…
Reference in New Issue