зеркало из https://github.com/microsoft/clang-1.git
When we're parsing an expression that may have looked like a
declaration, we can end up with template-id annotation tokens for types that have not been converted into type annotation tokens. When this is the case, translate the template-id into a type and parse as an expression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95404 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
ea48522e97
Коммит
ae4c77dc8a
|
@ -22,6 +22,7 @@
|
|||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "clang/Basic/PrettyStackTrace.h"
|
||||
#include "RAIIObjectsForParser.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
@ -806,9 +807,44 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
return ParsePostfixExpressionSuffix(move(Res));
|
||||
}
|
||||
|
||||
case tok::annot_cxxscope: // [C++] id-expression: qualified-id
|
||||
case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
|
||||
Token Next = NextToken();
|
||||
if (Next.is(tok::annot_template_id)) {
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
|
||||
if (TemplateId->Kind == TNK_Type_template) {
|
||||
// We have a qualified template-id that we know refers to a
|
||||
// type, translate it into a type and continue parsing as a
|
||||
// cast expression.
|
||||
CXXScopeSpec SS;
|
||||
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
|
||||
AnnotateTemplateIdTokenAsType(&SS);
|
||||
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
|
||||
NotCastExpr, TypeOfCast);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse as an id-expression.
|
||||
Res = ParseCXXIdExpression(isAddressOfOperand);
|
||||
return ParsePostfixExpressionSuffix(move(Res));
|
||||
}
|
||||
|
||||
case tok::annot_template_id: { // [C++] template-id
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
|
||||
if (TemplateId->Kind == TNK_Type_template) {
|
||||
// We have a template-id that we know refers to a type,
|
||||
// translate it into a type and continue parsing as a cast
|
||||
// expression.
|
||||
AnnotateTemplateIdTokenAsType();
|
||||
return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
|
||||
NotCastExpr, TypeOfCast);
|
||||
}
|
||||
|
||||
// Fall through to treat the template-id as an id-expression.
|
||||
}
|
||||
|
||||
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
|
||||
case tok::annot_template_id: // [C++] template-id
|
||||
Res = ParseCXXIdExpression(isAddressOfOperand);
|
||||
return ParsePostfixExpressionSuffix(move(Res));
|
||||
|
||||
|
|
|
@ -194,7 +194,9 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
|
|||
MultiExprArg exprs,
|
||||
SourceLocation *CommaLocs,
|
||||
SourceLocation RParenLoc) {
|
||||
assert(TypeRep && "Missing type!");
|
||||
if (!TypeRep)
|
||||
return ExprError();
|
||||
|
||||
TypeSourceInfo *TInfo;
|
||||
QualType Ty = GetTypeFromParser(TypeRep, &TInfo);
|
||||
if (!TInfo)
|
||||
|
|
|
@ -27,3 +27,20 @@ struct X0 {
|
|||
void test_X0_int(X0<int> xi, float f) {
|
||||
xi.f2(f);
|
||||
}
|
||||
|
||||
// Not template-id expressions, but they almost look like it.
|
||||
template<typename F>
|
||||
struct Y {
|
||||
Y(const F&);
|
||||
};
|
||||
|
||||
template<int I>
|
||||
struct X {
|
||||
X(int, int);
|
||||
void f() {
|
||||
Y<X<I> >(X<I>(0, 0));
|
||||
Y<X<I> >(::X<I>(0, 0));
|
||||
}
|
||||
};
|
||||
|
||||
template struct X<3>;
|
||||
|
|
Загрузка…
Ссылка в новой задаче