Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
angle
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
angle
Commits
46aa13d8
Commit
46aa13d8
authored
Jun 15, 2012
by
alokp@chromium.org
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented line directive.
Review URL:
https://codereview.appspot.com/6307083
git-svn-id:
https://angleproject.googlecode.com/svn/trunk@1149
736b8ea6-26fd-11df-bfd4-992fa37f6226
parent
7fc38ddd
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
217 additions
and
28 deletions
+217
-28
Diagnostics.h
src/compiler/preprocessor/new/Diagnostics.h
+8
-5
DirectiveParser.cpp
src/compiler/preprocessor/new/DirectiveParser.cpp
+56
-1
Tokenizer.cpp
src/compiler/preprocessor/new/Tokenizer.cpp
+12
-0
Tokenizer.h
src/compiler/preprocessor/new/Tokenizer.h
+4
-0
Tokenizer.l
src/compiler/preprocessor/new/Tokenizer.l
+12
-0
location_test.cpp
tests/preprocessor_tests/location_test.cpp
+125
-22
No files found.
src/compiler/preprocessor/new/Diagnostics.h
View file @
46aa13d8
...
...
@@ -19,6 +19,11 @@ struct SourceLocation;
class
Diagnostics
{
public
:
enum
Severity
{
ERROR
,
WARNING
};
enum
ID
{
ERROR_BEGIN
,
...
...
@@ -41,6 +46,9 @@ class Diagnostics
INVALID_EXTENSION_DIRECTIVE
,
INVALID_VERSION_NUMBER
,
INVALID_VERSION_DIRECTIVE
,
INVALID_LINE_NUMBER
,
INVALID_FILE_NUMBER
,
INVALID_LINE_DIRECTIVE
,
ERROR_END
,
WARNING_BEGIN
,
...
...
@@ -53,11 +61,6 @@ class Diagnostics
void
report
(
ID
id
,
const
SourceLocation
&
loc
,
const
std
::
string
&
text
);
protected
:
enum
Severity
{
ERROR
,
WARNING
};
Severity
severity
(
ID
id
);
virtual
void
print
(
ID
id
,
...
...
src/compiler/preprocessor/new/DirectiveParser.cpp
View file @
46aa13d8
...
...
@@ -472,10 +472,65 @@ void DirectiveParser::parseVersion(Token* token)
void
DirectiveParser
::
parseLine
(
Token
*
token
)
{
// TODO(alokp): Implement me.
assert
(
token
->
value
==
kDirectiveLine
);
enum
State
{
LINE_NUMBER
,
FILE_NUMBER
};
bool
valid
=
true
;
int
line
=
0
,
file
=
0
;
int
state
=
LINE_NUMBER
;
MacroExpander
macroExpander
(
mTokenizer
,
mMacroSet
,
mDiagnostics
);
macroExpander
.
lex
(
token
);
while
((
token
->
type
!=
'\n'
)
&&
(
token
->
type
!=
Token
::
LAST
))
{
switch
(
state
++
)
{
case
LINE_NUMBER
:
if
(
valid
&&
(
token
->
type
!=
Token
::
CONST_INT
))
{
mDiagnostics
->
report
(
Diagnostics
::
INVALID_LINE_NUMBER
,
token
->
location
,
token
->
value
);
valid
=
false
;
}
if
(
valid
)
line
=
atoi
(
token
->
value
.
c_str
());
break
;
case
FILE_NUMBER
:
if
(
valid
&&
(
token
->
type
!=
Token
::
CONST_INT
))
{
mDiagnostics
->
report
(
Diagnostics
::
INVALID_FILE_NUMBER
,
token
->
location
,
token
->
value
);
valid
=
false
;
}
if
(
valid
)
file
=
atoi
(
token
->
value
.
c_str
());
break
;
default
:
if
(
valid
)
{
mDiagnostics
->
report
(
Diagnostics
::
UNEXPECTED_TOKEN
,
token
->
location
,
token
->
value
);
valid
=
false
;
}
break
;
}
macroExpander
.
lex
(
token
);
}
if
(
valid
&&
(
state
!=
FILE_NUMBER
)
&&
(
state
!=
FILE_NUMBER
+
1
))
{
mDiagnostics
->
report
(
Diagnostics
::
INVALID_LINE_DIRECTIVE
,
token
->
location
,
token
->
value
);
valid
=
false
;
}
if
(
valid
)
{
mTokenizer
->
setLineNumber
(
line
);
if
(
state
==
FILE_NUMBER
+
1
)
mTokenizer
->
setFileNumber
(
file
);
}
}
}
// namespace pp
src/compiler/preprocessor/new/Tokenizer.cpp
View file @
46aa13d8
...
...
@@ -2302,6 +2302,18 @@ bool Tokenizer::init(int count, const char* const string[], const int length[])
return
initScanner
();
}
void
Tokenizer
::
setFileNumber
(
int
file
)
{
// We use column number as file number.
// See macro yyfileno.
ppset_column
(
file
,
mHandle
);
}
void
Tokenizer
::
setLineNumber
(
int
line
)
{
ppset_lineno
(
line
,
mHandle
);
}
void
Tokenizer
::
lex
(
Token
*
token
)
{
token
->
type
=
pplex
(
&
token
->
value
,
&
token
->
location
,
mHandle
);
...
...
src/compiler/preprocessor/new/Tokenizer.h
View file @
46aa13d8
...
...
@@ -37,6 +37,10 @@ class Tokenizer : public Lexer
~
Tokenizer
();
bool
init
(
int
count
,
const
char
*
const
string
[],
const
int
length
[]);
void
setFileNumber
(
int
file
);
void
setLineNumber
(
int
line
);
virtual
void
lex
(
Token
*
token
);
private
:
...
...
src/compiler/preprocessor/new/Tokenizer.l
View file @
46aa13d8
...
...
@@ -286,6 +286,18 @@ bool Tokenizer::init(int count, const char* const string[], const int length[])
return initScanner();
}
void Tokenizer::setFileNumber(int file)
{
// We use column number as file number.
// See macro yyfileno.
yyset_column(file, mHandle);
}
void Tokenizer::setLineNumber(int line)
{
yyset_lineno(line, mHandle);
}
void Tokenizer::lex(Token* token)
{
token->type = yylex(&token->value, &token->location, mHandle);
...
...
tests/preprocessor_tests/location_test.cpp
View file @
46aa13d8
...
...
@@ -30,9 +30,7 @@ protected:
TEST_F
(
LocationTest
,
String0_Line1
)
{
const
char
*
str
=
"foo"
;
pp
::
SourceLocation
loc
;
loc
.
file
=
0
;
loc
.
line
=
1
;
pp
::
SourceLocation
loc
(
0
,
1
);
SCOPED_TRACE
(
"String0_Line1"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
...
...
@@ -41,9 +39,7 @@ TEST_F(LocationTest, String0_Line1)
TEST_F
(
LocationTest
,
String0_Line2
)
{
const
char
*
str
=
"
\n
foo"
;
pp
::
SourceLocation
loc
;
loc
.
file
=
0
;
loc
.
line
=
2
;
pp
::
SourceLocation
loc
(
0
,
2
);
SCOPED_TRACE
(
"String0_Line2"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
...
...
@@ -52,9 +48,7 @@ TEST_F(LocationTest, String0_Line2)
TEST_F
(
LocationTest
,
String1_Line1
)
{
const
char
*
const
str
[]
=
{
"
\n\n
"
,
"foo"
};
pp
::
SourceLocation
loc
;
loc
.
file
=
1
;
loc
.
line
=
1
;
pp
::
SourceLocation
loc
(
1
,
1
);
SCOPED_TRACE
(
"String1_Line1"
);
expectLocation
(
2
,
str
,
NULL
,
loc
);
...
...
@@ -63,9 +57,7 @@ TEST_F(LocationTest, String1_Line1)
TEST_F
(
LocationTest
,
String1_Line2
)
{
const
char
*
const
str
[]
=
{
"
\n\n
"
,
"
\n
foo"
};
pp
::
SourceLocation
loc
;
loc
.
file
=
1
;
loc
.
line
=
2
;
pp
::
SourceLocation
loc
(
1
,
2
);
SCOPED_TRACE
(
"String1_Line2"
);
expectLocation
(
2
,
str
,
NULL
,
loc
);
...
...
@@ -74,9 +66,7 @@ TEST_F(LocationTest, String1_Line2)
TEST_F
(
LocationTest
,
NewlineInsideCommentCounted
)
{
const
char
*
str
=
"/*
\n\n
*/foo"
;
pp
::
SourceLocation
loc
;
loc
.
file
=
0
;
loc
.
line
=
3
;
pp
::
SourceLocation
loc
(
0
,
3
);
SCOPED_TRACE
(
"NewlineInsideCommentCounted"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
...
...
@@ -101,9 +91,7 @@ TEST_F(LocationTest, ErrorLocationAfterComment)
TEST_F
(
LocationTest
,
TokenStraddlingTwoStrings
)
{
const
char
*
const
str
[]
=
{
"f"
,
"oo"
};
pp
::
SourceLocation
loc
;
loc
.
file
=
0
;
loc
.
line
=
1
;
pp
::
SourceLocation
loc
(
0
,
1
);
SCOPED_TRACE
(
"TokenStraddlingTwoStrings"
);
expectLocation
(
2
,
str
,
NULL
,
loc
);
...
...
@@ -112,9 +100,7 @@ TEST_F(LocationTest, TokenStraddlingTwoStrings)
TEST_F
(
LocationTest
,
TokenStraddlingThreeStrings
)
{
const
char
*
const
str
[]
=
{
"f"
,
"o"
,
"o"
};
pp
::
SourceLocation
loc
;
loc
.
file
=
0
;
loc
.
line
=
1
;
pp
::
SourceLocation
loc
(
0
,
1
);
SCOPED_TRACE
(
"TokenStraddlingThreeStrings"
);
expectLocation
(
3
,
str
,
NULL
,
loc
);
...
...
@@ -174,4 +160,121 @@ TEST_F(LocationTest, EndOfFileAfterEmptyString)
EXPECT_EQ
(
1
,
token
.
location
.
line
);
}
// TODO(alokp): Add tests for #line directives.
TEST_F
(
LocationTest
,
ValidLineDirective1
)
{
const
char
*
str
=
"#line 10
\n
"
"foo"
;
pp
::
SourceLocation
loc
(
0
,
10
);
SCOPED_TRACE
(
"ValidLineDirective1"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
}
TEST_F
(
LocationTest
,
ValidLineDirective2
)
{
const
char
*
str
=
"#line 10 20
\n
"
"foo"
;
pp
::
SourceLocation
loc
(
20
,
10
);
SCOPED_TRACE
(
"ValidLineDirective2"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
}
TEST_F
(
LocationTest
,
LineDirectiveCommentsIgnored
)
{
const
char
*
str
=
"/* bar */"
"#"
"/* bar */"
"line"
"/* bar */"
"10"
"/* bar */"
"20"
"/* bar */"
"// bar "
"
\n
"
"foo"
;
pp
::
SourceLocation
loc
(
20
,
10
);
SCOPED_TRACE
(
"LineDirectiveCommentsIgnored"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
}
TEST_F
(
LocationTest
,
LineDirectiveWithMacro
)
{
const
char
*
str
=
"#define L 10
\n
"
"#define F(x) x
\n
"
"#line L F(20)
\n
"
"foo"
;
pp
::
SourceLocation
loc
(
20
,
10
);
SCOPED_TRACE
(
"LineDirectiveWithMacro"
);
expectLocation
(
1
,
&
str
,
NULL
,
loc
);
}
TEST_F
(
LocationTest
,
LineDirectiveNewlineBeforeStringBreak
)
{
const
char
*
const
str
[]
=
{
"#line 10 20
\n
"
,
"foo"
};
// String number is incremented after it is set by the line directive.
// Also notice that line number is reset after the string break.
pp
::
SourceLocation
loc
(
21
,
1
);
SCOPED_TRACE
(
"LineDirectiveNewlineBeforeStringBreak"
);
expectLocation
(
2
,
str
,
NULL
,
loc
);
}
TEST_F
(
LocationTest
,
LineDirectiveNewlineAfterStringBreak
)
{
const
char
*
const
str
[]
=
{
"#line 10 20"
,
"
\n
foo"
};
// String number is incremented before it is set by the line directive.
pp
::
SourceLocation
loc
(
20
,
10
);
SCOPED_TRACE
(
"LineDirectiveNewlineAfterStringBreak"
);
expectLocation
(
2
,
str
,
NULL
,
loc
);
}
TEST_F
(
LocationTest
,
LineDirectiveMissingNewline
)
{
const
char
*
str
=
"#line 10"
;
ASSERT_TRUE
(
mPreprocessor
.
init
(
1
,
&
str
,
NULL
));
using
testing
::
_
;
// Error reported about EOF.
EXPECT_CALL
(
mDiagnostics
,
print
(
pp
::
Diagnostics
::
EOF_IN_DIRECTIVE
,
_
,
_
));
pp
::
Token
token
;
mPreprocessor
.
lex
(
&
token
);
}
struct
LineTestParam
{
const
char
*
str
;
pp
::
Diagnostics
::
ID
id
;
};
class
InvalidLineTest
:
public
LocationTest
,
public
testing
::
WithParamInterface
<
LineTestParam
>
{
};
TEST_P
(
InvalidLineTest
,
Identified
)
{
LineTestParam
param
=
GetParam
();
ASSERT_TRUE
(
mPreprocessor
.
init
(
1
,
&
param
.
str
,
NULL
));
using
testing
::
_
;
// Invalid line directive call.
EXPECT_CALL
(
mDiagnostics
,
print
(
param
.
id
,
pp
::
SourceLocation
(
0
,
1
),
_
));
pp
::
Token
token
;
mPreprocessor
.
lex
(
&
token
);
}
static
const
LineTestParam
kParams
[]
=
{
{
"#line
\n
"
,
pp
::
Diagnostics
::
INVALID_LINE_DIRECTIVE
},
{
"#line foo
\n
"
,
pp
::
Diagnostics
::
INVALID_LINE_NUMBER
},
{
"#line 10 foo
\n
"
,
pp
::
Diagnostics
::
INVALID_FILE_NUMBER
},
{
"#line 10 20 foo
\n
"
,
pp
::
Diagnostics
::
UNEXPECTED_TOKEN
}
};
INSTANTIATE_TEST_CASE_P
(
All
,
InvalidLineTest
,
testing
::
ValuesIn
(
kParams
));
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment