Use ParseUnqualifiedId when parsing id-expressions. This eliminates
yet another copy of the unqualified-id parsing code.
Also, use UnqualifiedId to simplify the Action interface for building
id-expressions. ActOnIdentifierExpr, ActOnCXXOperatorFunctionIdExpr,
ActOnCXXConversionFunctionExpr, and ActOnTemplateIdExpr have all been
removed in favor of the new ActOnIdExpression action.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85904 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 477e6fb..12025c6 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -651,7 +651,11 @@
// Function designators are allowed to be undeclared (C99 6.5.1p2), so we
// need to know whether or not this identifier is a function designator or
// not.
- Res = Actions.ActOnIdentifierExpr(CurScope, ILoc, II, Tok.is(tok::l_paren));
+ UnqualifiedId Name;
+ CXXScopeSpec ScopeSpec;
+ Name.setIdentifier(&II, ILoc);
+ Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name,
+ Tok.is(tok::l_paren), false);
// These can be followed by postfix-expr pieces.
return ParsePostfixExpressionSuffix(move(Res));
}
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index dc79741..b125035 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -309,7 +309,19 @@
//
CXXScopeSpec SS;
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
-
+
+ UnqualifiedId Name;
+ if (ParseUnqualifiedId(SS,
+ /*EnteringContext=*/false,
+ /*AllowDestructorName=*/false,
+ /*AllowConstructorName=*/false,
+ Name))
+ return ExprError();
+
+ return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
+ isAddressOfOperand);
+
+#if 0
// unqualified-id:
// identifier
// operator-function-id
@@ -372,6 +384,7 @@
} // switch.
assert(0 && "The switch was supposed to take care everything.");
+#endif
}
/// ParseCXXCasts - This handles the various ways to cast expressions to another
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3281fc4..18dcd85 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -474,6 +474,7 @@
/// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo.
QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo);
DeclarationName GetNameForDeclarator(Declarator &D);
+ DeclarationName GetNameFromUnqualifiedId(UnqualifiedId &Name);
static QualType GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo = 0);
bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
@@ -1608,23 +1609,12 @@
// Primary Expressions.
virtual SourceRange getExprRange(ExprTy *E) const;
- virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
- IdentifierInfo &II,
- bool HasTrailingLParen,
- const CXXScopeSpec *SS = 0,
- bool isAddressOfOperand = false);
- virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S,
- SourceLocation OperatorLoc,
- OverloadedOperatorKind Op,
- bool HasTrailingLParen,
- const CXXScopeSpec &SS,
- bool isAddressOfOperand);
- virtual OwningExprResult ActOnCXXConversionFunctionExpr(Scope *S,
- SourceLocation OperatorLoc,
- TypeTy *Ty,
- bool HasTrailingLParen,
- const CXXScopeSpec &SS,
- bool isAddressOfOperand);
+ virtual OwningExprResult ActOnIdExpression(Scope *S,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ bool HasTrailingLParen,
+ bool IsAddressOfOperand);
+
OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
SourceLocation Loc, bool TypeDependent,
bool ValueDependent,
@@ -2545,13 +2535,13 @@
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
- virtual OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc);
+ OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc);
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
const IdentifierInfo &Name,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 8d00c09..82d467f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1606,56 +1606,60 @@
/// GetNameForDeclarator - Determine the full declaration name for the
/// given Declarator.
DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
- UnqualifiedId &Name = D.getName();
+ return GetNameFromUnqualifiedId(D.getName());
+}
+
+/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
+DeclarationName Sema::GetNameFromUnqualifiedId(UnqualifiedId &Name) {
switch (Name.getKind()) {
- case UnqualifiedId::IK_Identifier:
- return DeclarationName(Name.Identifier);
-
- case UnqualifiedId::IK_OperatorFunctionId:
- return Context.DeclarationNames.getCXXOperatorName(
- Name.OperatorFunctionId.Operator);
-
- case UnqualifiedId::IK_ConversionFunctionId: {
- QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
- if (Ty.isNull())
- return DeclarationName();
-
- return Context.DeclarationNames.getCXXConversionFunctionName(
- Context.getCanonicalType(Ty));
- }
+ case UnqualifiedId::IK_Identifier:
+ return DeclarationName(Name.Identifier);
- case UnqualifiedId::IK_ConstructorName: {
- QualType Ty = GetTypeFromParser(Name.ConstructorName);
- if (Ty.isNull())
- return DeclarationName();
-
- return Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(Ty));
- }
+ case UnqualifiedId::IK_OperatorFunctionId:
+ return Context.DeclarationNames.getCXXOperatorName(
+ Name.OperatorFunctionId.Operator);
- case UnqualifiedId::IK_DestructorName: {
- QualType Ty = GetTypeFromParser(Name.DestructorName);
- if (Ty.isNull())
- return DeclarationName();
-
- return Context.DeclarationNames.getCXXDestructorName(
- Context.getCanonicalType(Ty));
- }
+ case UnqualifiedId::IK_ConversionFunctionId: {
+ QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
+ if (Ty.isNull())
+ return DeclarationName();
- case UnqualifiedId::IK_TemplateId: {
- TemplateName TName
+ return Context.DeclarationNames.getCXXConversionFunctionName(
+ Context.getCanonicalType(Ty));
+ }
+
+ case UnqualifiedId::IK_ConstructorName: {
+ QualType Ty = GetTypeFromParser(Name.ConstructorName);
+ if (Ty.isNull())
+ return DeclarationName();
+
+ return Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(Ty));
+ }
+
+ case UnqualifiedId::IK_DestructorName: {
+ QualType Ty = GetTypeFromParser(Name.DestructorName);
+ if (Ty.isNull())
+ return DeclarationName();
+
+ return Context.DeclarationNames.getCXXDestructorName(
+ Context.getCanonicalType(Ty));
+ }
+
+ case UnqualifiedId::IK_TemplateId: {
+ TemplateName TName
= TemplateName::getFromVoidPointer(Name.TemplateId->Template);
- if (TemplateDecl *Template = TName.getAsTemplateDecl())
- return Template->getDeclName();
- if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
- return Ovl->getDeclName();
-
- return DeclarationName();
+ if (TemplateDecl *Template = TName.getAsTemplateDecl())
+ return Template->getDeclName();
+ if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
+ return Ovl->getDeclName();
+
+ return DeclarationName();
+ }
}
- }
-
+
assert(false && "Unknown name kind");
- return DeclarationName();
+ return DeclarationName();
}
/// isNearlyMatchingFunction - Determine whether the C++ functions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index bdfe91e..63d39a0 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -436,20 +436,6 @@
-/// ActOnIdentifierExpr - The parser read an identifier in expression context,
-/// validate it per-C99 6.5.1. HasTrailingLParen indicates whether this
-/// identifier is used in a function call context.
-/// SS is only used for a C++ qualified-id (foo::bar) to indicate the
-/// class or namespace that the identifier must be a member of.
-Sema::OwningExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
- IdentifierInfo &II,
- bool HasTrailingLParen,
- const CXXScopeSpec *SS,
- bool isAddressOfOperand) {
- return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS,
- isAddressOfOperand);
-}
-
/// BuildDeclRefExpr - Build a DeclRefExpr.
Sema::OwningExprResult
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
@@ -654,15 +640,43 @@
return Owned(Result);
}
+Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &Name,
+ bool HasTrailingLParen,
+ bool IsAddressOfOperand) {
+ if (Name.getKind() == UnqualifiedId::IK_TemplateId) {
+ ASTTemplateArgsPtr TemplateArgsPtr(*this,
+ Name.TemplateId->getTemplateArgs(),
+ Name.TemplateId->getTemplateArgIsType(),
+ Name.TemplateId->NumArgs);
+ return ActOnTemplateIdExpr(SS,
+ TemplateTy::make(Name.TemplateId->Template),
+ Name.TemplateId->TemplateNameLoc,
+ Name.TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ Name.TemplateId->getTemplateArgLocations(),
+ Name.TemplateId->RAngleLoc);
+ }
+
+ // FIXME: We lose a bunch of source information by doing this. Later,
+ // we'll want to merge ActOnDeclarationNameExpr's logic into
+ // ActOnIdExpression.
+ return ActOnDeclarationNameExpr(S,
+ Name.StartLocation,
+ GetNameFromUnqualifiedId(Name),
+ HasTrailingLParen,
+ &SS,
+ IsAddressOfOperand);
+}
+
/// ActOnDeclarationNameExpr - The parser has read some kind of name
/// (e.g., a C++ id-expression (C++ [expr.prim]p1)). This routine
/// performs lookup on that name and returns an expression that refers
/// to that name. This routine isn't directly called from the parser,
/// because the parser doesn't know about DeclarationName. Rather,
-/// this routine is called by ActOnIdentifierExpr,
-/// ActOnOperatorFunctionIdExpr, and ActOnConversionFunctionExpr,
-/// which form the DeclarationName from the corresponding syntactic
-/// forms.
+/// this routine is called by ActOnIdExpression, which contains a
+/// parsed UnqualifiedId.
///
/// HasTrailingLParen indicates whether this identifier is used in a
/// function call context. LookupCtx is only used for a C++
@@ -743,8 +757,11 @@
// FIXME: This should use a new expr for a direct reference, don't
// turn this into Self->ivar, just return a BareIVarExpr or something.
IdentifierInfo &II = Context.Idents.get("self");
- OwningExprResult SelfExpr = ActOnIdentifierExpr(S, SourceLocation(),
- II, false);
+ UnqualifiedId SelfName;
+ SelfName.setIdentifier(&II, SourceLocation());
+ CXXScopeSpec SelfScopeSpec;
+ OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+ SelfName, false, false);
MarkDeclarationReferenced(Loc, IV);
return Owned(new (Context)
ObjCIvarRefExpr(IV, IV->getType(), Loc,
@@ -3985,7 +4002,7 @@
// This check seems unnatural, however it is necessary to ensure the proper
// conversion of functions/arrays. If the conversion were done for all
- // DeclExpr's (created by ActOnIdentifierExpr), it would mess up the unary
+ // DeclExpr's (created by ActOnIdExpression), it would mess up the unary
// expressions that surpress this implicit conversion (&, sizeof).
//
// Suppress this for references: C++ 8.5.3p5.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index fad1f3e..10fff0e 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -22,41 +22,6 @@
#include "llvm/ADT/STLExtras.h"
using namespace clang;
-/// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function
-/// name (e.g., operator void const *) as an expression. This is
-/// very similar to ActOnIdentifierExpr, except that instead of
-/// providing an identifier the parser provides the type of the
-/// conversion function.
-Sema::OwningExprResult
-Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc,
- TypeTy *Ty, bool HasTrailingLParen,
- const CXXScopeSpec &SS,
- bool isAddressOfOperand) {
- //FIXME: Preserve type source info.
- QualType ConvType = GetTypeFromParser(Ty);
- CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
- DeclarationName ConvName
- = Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
- return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen,
- &SS, isAddressOfOperand);
-}
-
-/// ActOnCXXOperatorFunctionIdExpr - Parse a C++ overloaded operator
-/// name (e.g., @c operator+ ) as an expression. This is very
-/// similar to ActOnIdentifierExpr, except that instead of providing
-/// an identifier the parser provides the kind of overloaded
-/// operator that was parsed.
-Sema::OwningExprResult
-Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc,
- OverloadedOperatorKind Op,
- bool HasTrailingLParen,
- const CXXScopeSpec &SS,
- bool isAddressOfOperand) {
- DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(Op);
- return ActOnDeclarationNameExpr(S, OperatorLoc, Name, HasTrailingLParen, &SS,
- isAddressOfOperand);
-}
-
/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
Action::OwningExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,