r201536 - PR18870: Parse language linkage specifiers properly if the string-literal is
Richard Smith
richard-llvm at metafoo.co.uk
Mon Feb 17 15:25:28 PST 2014
Author: rsmith
Date: Mon Feb 17 17:25:27 2014
New Revision: 201536
URL: http://llvm.org/viewvc/llvm-project?rev=201536&view=rev
Log:
PR18870: Parse language linkage specifiers properly if the string-literal is
spelled in an interesting way.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/Parser/cxx11-user-defined-literals.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=201536&r1=201535&r2=201536&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Feb 17 17:25:27 2014
@@ -222,7 +222,10 @@ def note_function_suggestion : Note<"did
def err_ellipsis_first_arg : Error<
"ISO C requires a named argument before '...'">;
def err_declarator_need_ident : Error<"declarator requires an identifier">;
-def err_bad_language : Error<"unknown linkage language">;
+def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
+def err_language_linkage_spec_not_ascii : Error<
+ "string literal in language linkage specifier cannot have an "
+ "encoding-prefix">;
def warn_use_out_of_scope_declaration : Warning<
"use of out-of-scope declaration of %0">;
def err_inline_non_function : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=201536&r1=201535&r2=201536&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Feb 17 17:25:27 2014
@@ -4661,8 +4661,7 @@ public:
//
Decl *ActOnStartLinkageSpecification(Scope *S,
SourceLocation ExternLoc,
- SourceLocation LangLoc,
- StringRef Lang,
+ Expr *LangStr,
SourceLocation LBraceLoc);
Decl *ActOnFinishLinkageSpecification(Scope *S,
Decl *LinkageSpec,
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=201536&r1=201535&r2=201536&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Feb 17 17:25:27 2014
@@ -279,27 +279,16 @@ Decl *Parser::ParseNamespaceAlias(Source
/// 'extern' string-literal declaration
///
Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
- assert(Tok.is(tok::string_literal) && "Not a string literal!");
- SmallString<8> LangBuffer;
- bool Invalid = false;
- StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
- if (Invalid)
- return 0;
-
- // FIXME: This is incorrect: linkage-specifiers are parsed in translation
- // phase 7, so string-literal concatenation is supposed to occur.
- // extern "" "C" "" "+" "+" { } is legal.
- if (Tok.hasUDSuffix())
- Diag(Tok, diag::err_invalid_string_udl);
- SourceLocation Loc = ConsumeStringToken();
+ assert(isTokenStringLiteral() && "Not a string literal!");
+ ExprResult Lang = ParseStringLiteralExpression(false);
ParseScope LinkageScope(this, Scope::DeclScope);
- Decl *LinkageSpec
- = Actions.ActOnStartLinkageSpecification(getCurScope(),
- DS.getSourceRange().getBegin(),
- Loc, Lang,
- Tok.is(tok::l_brace) ? Tok.getLocation()
- : SourceLocation());
+ Decl *LinkageSpec =
+ Lang.isInvalid()
+ ? 0
+ : Actions.ActOnStartLinkageSpecification(
+ getCurScope(), DS.getSourceRange().getBegin(), Lang.take(),
+ Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX11Attributes(attrs);
@@ -313,8 +302,9 @@ Decl *Parser::ParseLinkage(ParsingDeclSp
// ... but anyway remember that such an "extern" was seen.
DS.setExternInLinkageSpec(true);
ParseExternalDeclaration(attrs, &DS);
- return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
- SourceLocation());
+ return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
+ getCurScope(), LinkageSpec, SourceLocation())
+ : 0;
}
DS.abort();
@@ -331,8 +321,9 @@ Decl *Parser::ParseLinkage(ParsingDeclSp
}
T.consumeClose();
- return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
- T.getCloseLocation());
+ return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
+ getCurScope(), LinkageSpec, T.getCloseLocation())
+ : 0;
}
/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=201536&r1=201535&r2=201536&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Feb 17 17:25:27 2014
@@ -830,7 +830,6 @@ Parser::ParseExternalDeclaration(ParsedA
ParseExplicitInstantiation(Declarator::FileContext,
ExternLoc, TemplateLoc, DeclEnd));
}
- // FIXME: Detect C++ linkage specifications here?
goto dont_know;
case tok::kw___if_exists:
@@ -960,7 +959,7 @@ Parser::ParseDeclOrFunctionDefInternal(P
// If the declspec consisted only of 'extern' and we have a string
// literal following it, this must be a C++ linkage specifier like
// 'extern "C"'.
- if (Tok.is(tok::string_literal) && getLangOpts().CPlusPlus &&
+ if (getLangOpts().CPlusPlus && isTokenStringLiteral() &&
DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=201536&r1=201535&r2=201536&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Feb 17 17:25:27 2014
@@ -11071,29 +11071,36 @@ FinishedParams:
/// ActOnStartLinkageSpecification - Parsed the beginning of a C++
/// linkage specification, including the language and (if present)
-/// the '{'. ExternLoc is the location of the 'extern', LangLoc is
-/// the location of the language string literal, which is provided
-/// by Lang/StrSize. LBraceLoc, if valid, provides the location of
+/// the '{'. ExternLoc is the location of the 'extern', Lang is the
+/// language string literal. LBraceLoc, if valid, provides the location of
/// the '{' brace. Otherwise, this linkage specification does not
/// have any braces.
Decl *Sema::ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc,
- SourceLocation LangLoc,
- StringRef Lang,
+ Expr *LangStr,
SourceLocation LBraceLoc) {
+ StringLiteral *Lit = cast<StringLiteral>(LangStr);
+ if (!Lit->isAscii()) {
+ Diag(LangStr->getExprLoc(), diag::err_language_linkage_spec_not_ascii)
+ << LangStr->getSourceRange();
+ return 0;
+ }
+
+ StringRef Lang = Lit->getString();
LinkageSpecDecl::LanguageIDs Language;
- if (Lang == "\"C\"")
+ if (Lang == "C")
Language = LinkageSpecDecl::lang_c;
- else if (Lang == "\"C++\"")
+ else if (Lang == "C++")
Language = LinkageSpecDecl::lang_cxx;
else {
- Diag(LangLoc, diag::err_bad_language);
+ Diag(LangStr->getExprLoc(), diag::err_language_linkage_spec_unknown)
+ << LangStr->getSourceRange();
return 0;
}
// FIXME: Add all the various semantics of linkage specifications
- LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext,
- ExternLoc, LangLoc, Language,
+ LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext, ExternLoc,
+ LangStr->getExprLoc(), Language,
LBraceLoc.isValid());
CurContext->addDecl(D);
PushDeclContext(S, D);
@@ -11107,13 +11114,11 @@ Decl *Sema::ActOnStartLinkageSpecificati
Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
Decl *LinkageSpec,
SourceLocation RBraceLoc) {
- if (LinkageSpec) {
- if (RBraceLoc.isValid()) {
- LinkageSpecDecl* LSDecl = cast<LinkageSpecDecl>(LinkageSpec);
- LSDecl->setRBraceLoc(RBraceLoc);
- }
- PopDeclContext();
+ if (RBraceLoc.isValid()) {
+ LinkageSpecDecl* LSDecl = cast<LinkageSpecDecl>(LinkageSpec);
+ LSDecl->setRBraceLoc(RBraceLoc);
}
+ PopDeclContext();
return LinkageSpec;
}
Modified: cfe/trunk/test/Parser/cxx11-user-defined-literals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx11-user-defined-literals.cpp?rev=201536&r1=201535&r2=201536&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx11-user-defined-literals.cpp (original)
+++ cfe/trunk/test/Parser/cxx11-user-defined-literals.cpp Mon Feb 17 17:25:27 2014
@@ -15,7 +15,7 @@ _Pragma("comment(lib, \"foo\"_bar)") //
#elif __has_include("foo"_bar) // expected-error {{expected "FILENAME" or <FILENAME>}}
#endif
-extern "C++"_x {} // expected-error {{user-defined suffix cannot be used here}} expected-error {{unknown linkage language}}
+extern "C++"_x {} // expected-error {{user-defined suffix cannot be used here}}
int f() {
asm("mov %eax, %rdx"_foo); // expected-error {{user-defined suffix cannot be used here}}
More information about the cfe-commits
mailing list