Introduce a new OpaquePtr<N> struct type, which is a simple POD wrapper for a
pointer. Its purpose in life is to be a glorified void*, but which does not
implicitly convert to void* or other OpaquePtr's with a different UID.
Introduce Action::DeclPtrTy which is a typedef for OpaquePtr<0>. Change the
entire parser/sema interface to use DeclPtrTy instead of DeclTy*. This
makes the C++ compiler enforce that these aren't convertible to other opaque
types.
We should also convert ExprTy, StmtTy, TypeTy, AttrTy, BaseTy, etc,
but I don't plan to do that in the short term.
The one outstanding known problem with this patch is that we lose the
bitmangling optimization where ActionResult<DeclPtrTy> doesn't know how to
bitmangle the success bit into the low bit of DeclPtrTy. I will rectify
this with a subsequent patch.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 121bf04..37eb34e 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -42,7 +42,7 @@
/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
/// 'namespace' identifier '=' qualified-namespace-specifier ';'
///
-Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
@@ -55,7 +55,7 @@
}
// Read label attributes, if present.
- DeclTy *AttrList = 0;
+ Action::AttrTy *AttrList = 0;
if (Tok.is(tok::kw___attribute))
// FIXME: save these somewhere.
AttrList = ParseAttributes();
@@ -70,7 +70,7 @@
// Enter a scope for the namespace.
ParseScope NamespaceScope(this, Scope::DeclScope);
- DeclTy *NamespcDecl =
+ DeclPtrTy NamespcDecl =
Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
@@ -93,14 +93,14 @@
diag::err_expected_ident_lbrace);
}
- return 0;
+ return DeclPtrTy();
}
/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
/// alias definition.
///
-Parser::DeclTy *Parser::ParseNamespaceAlias(SourceLocation AliasLoc,
- IdentifierInfo *Alias) {
+Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation AliasLoc,
+ IdentifierInfo *Alias) {
assert(Tok.is(tok::equal) && "Not equal token");
ConsumeToken(); // eat the '='.
@@ -113,7 +113,7 @@
Diag(Tok, diag::err_expected_namespace_name);
// Skip to end of the definition and eat the ';'.
SkipUntil(tok::semi);
- return 0;
+ return DeclPtrTy();
}
// Parse identifier.
@@ -135,7 +135,7 @@
/// 'extern' string-literal '{' declaration-seq[opt] '}'
/// 'extern' string-literal declaration
///
-Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseLinkage(unsigned Context) {
assert(Tok.is(tok::string_literal) && "Not a string literal!");
llvm::SmallVector<char, 8> LangBuffer;
// LangBuffer is guaranteed to be big enough.
@@ -146,7 +146,7 @@
SourceLocation Loc = ConsumeStringToken();
ParseScope LinkageScope(this, Scope::DeclScope);
- DeclTy *LinkageSpec
+ DeclPtrTy LinkageSpec
= Actions.ActOnStartLinkageSpecification(CurScope,
/*FIXME: */SourceLocation(),
Loc, LangBufPtr, StrSize,
@@ -170,7 +170,7 @@
/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
/// using-directive. Assumes that current token is 'using'.
-Parser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
assert(Tok.is(tok::kw_using) && "Not using token");
// Eat 'using'.
@@ -194,8 +194,8 @@
/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
/// namespace-name attributes[opt] ;
///
-Parser::DeclTy *Parser::ParseUsingDirective(unsigned Context,
- SourceLocation UsingLoc) {
+Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
+ SourceLocation UsingLoc) {
assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
// Eat 'namespace'.
@@ -215,7 +215,7 @@
// If there was invalid namespace name, skip to end of decl, and eat ';'.
SkipUntil(tok::semi);
// FIXME: Are there cases, when we would like to call ActOnUsingDirective?
- return 0;
+ return DeclPtrTy();
}
// Parse identifier.
@@ -242,11 +242,11 @@
/// unqualified-id [TODO]
/// 'using' :: unqualified-id [TODO]
///
-Parser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context,
- SourceLocation UsingLoc) {
+Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
+ SourceLocation UsingLoc) {
assert(false && "Not implemented");
// FIXME: Implement parsing.
- return 0;
+ return DeclPtrTy();
}
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
@@ -254,13 +254,13 @@
/// static_assert-declaration:
/// static_assert ( constant-expression , string-literal ) ;
///
-Parser::DeclTy *Parser::ParseStaticAssertDeclaration() {
+Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
SourceLocation StaticAssertLoc = ConsumeToken();
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen);
- return 0;
+ return DeclPtrTy();
}
SourceLocation LParenLoc = ConsumeParen();
@@ -268,21 +268,21 @@
OwningExprResult AssertExpr(ParseConstantExpression());
if (AssertExpr.isInvalid()) {
SkipUntil(tok::semi);
- return 0;
+ return DeclPtrTy();
}
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
- return 0;
+ return DeclPtrTy();
if (Tok.isNot(tok::string_literal)) {
Diag(Tok, diag::err_expected_string_literal);
SkipUntil(tok::semi);
- return 0;
+ return DeclPtrTy();
}
OwningExprResult AssertMessage(ParseStringLiteralExpression());
if (AssertMessage.isInvalid())
- return 0;
+ return DeclPtrTy();
MatchRHSPunctuation(tok::r_paren, LParenLoc);
@@ -475,7 +475,7 @@
TagOrTempResult
= Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
StartLoc, SS,
- TemplateId->Template,
+ DeclPtrTy::make(TemplateId->Template),
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
@@ -518,7 +518,7 @@
if (TagOrTempResult.isInvalid())
DS.SetTypeSpecError();
else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
- TagOrTempResult.get()))
+ TagOrTempResult.get().getAs<void>()))
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
}
@@ -529,8 +529,7 @@
/// base-specifier-list:
/// base-specifier '...'[opt]
/// base-specifier-list ',' base-specifier '...'[opt]
-void Parser::ParseBaseClause(DeclTy *ClassDecl)
-{
+void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
assert(Tok.is(tok::colon) && "Not a base clause");
ConsumeToken();
@@ -572,8 +571,7 @@
/// class-name
/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
/// class-name
-Parser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl)
-{
+Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
bool IsVirtual = false;
SourceLocation StartLoc = Tok.getLocation();
@@ -666,7 +664,7 @@
/// constant-initializer:
/// '=' constant-expression
///
-Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
+Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// static_assert-declaration
if (Tok.is(tok::kw_static_assert))
return ParseStaticAssertDeclaration();
@@ -702,7 +700,7 @@
return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
default:
Diag(DSStart, diag::err_no_declarators);
- return 0;
+ return DeclPtrTy();
}
}
@@ -717,7 +715,7 @@
SkipUntil(tok::r_brace, true);
if (Tok.is(tok::semi))
ConsumeToken();
- return 0;
+ return DeclPtrTy();
}
// function-definition:
@@ -727,7 +725,7 @@
Diag(Tok, diag::err_func_def_no_params);
ConsumeBrace();
SkipUntil(tok::r_brace, true);
- return 0;
+ return DeclPtrTy();
}
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
@@ -737,7 +735,7 @@
// assumes the declarator represents a function, not a typedef.
ConsumeBrace();
SkipUntil(tok::r_brace, true);
- return 0;
+ return DeclPtrTy();
}
return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
@@ -748,7 +746,7 @@
// member-declarator
// member-declarator-list ',' member-declarator
- DeclTy *LastDeclInGroup = 0;
+ DeclPtrTy LastDeclInGroup;
OwningExprResult BitfieldSize(Actions);
OwningExprResult Init(Actions);
@@ -865,7 +863,7 @@
SkipUntil(tok::r_brace, true, true);
if (Tok.is(tok::semi))
ConsumeToken();
- return 0;
+ return DeclPtrTy();
}
/// ParseCXXMemberSpecification - Parse the class definition.
@@ -875,7 +873,7 @@
/// access-specifier ':' member-specification[opt]
///
void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
- unsigned TagType, DeclTy *TagDecl) {
+ unsigned TagType, DeclPtrTy TagDecl) {
assert((TagType == DeclSpec::TST_struct ||
TagType == DeclSpec::TST_union ||
TagType == DeclSpec::TST_class) && "Invalid TagType!");
@@ -997,7 +995,7 @@
/// [C++] mem-initializer-list:
/// mem-initializer
/// mem-initializer , mem-initializer-list
-void Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) {
+void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
SourceLocation ColonLoc = ConsumeToken();
@@ -1035,7 +1033,7 @@
/// [C++] mem-initializer-id:
/// '::'[opt] nested-name-specifier[opt] class-name
/// identifier
-Parser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) {
+Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
// FIXME: parse '::'[opt] nested-name-specifier[opt]
if (Tok.isNot(tok::identifier)) {