Basic support for formatting asm() statments.

llvm-svn: 177073
This commit is contained in:
Daniel Jasper 2013-03-14 13:45:21 +00:00
parent a097f7b1e3
commit 40aacf4872
4 changed files with 36 additions and 17 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -34,6 +34,7 @@ enum TokenType {
TT_ConditionalExpr,
TT_CtorInitializerColon,
TT_ImplicitStringLiteral,
TT_InlineASMColon,
TT_InheritanceColon,
TT_LineComment,
TT_ObjCArrayLiteral,

View File

@ -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.