aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTConsumer.h6
-rw-r--r--include/clang/AST/DeclBase.h17
-rw-r--r--include/clang/AST/DeclGroup.h12
-rw-r--r--include/clang/Parse/Action.h34
-rw-r--r--include/clang/Parse/Parser.h15
-rw-r--r--lib/AST/ASTConsumer.cpp5
-rw-r--r--lib/AST/DeclGroup.cpp17
-rw-r--r--lib/AST/DeclSerialization.cpp2
-rw-r--r--lib/AST/StmtIterator.cpp9
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp12
-rw-r--r--lib/Parse/MinimalAction.cpp2
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp3
-rw-r--r--lib/Parse/ParseDecl.cpp59
-rw-r--r--lib/Parse/ParseDeclCXX.cpp66
-rw-r--r--lib/Parse/ParseObjc.cpp15
-rw-r--r--lib/Parse/ParseStmt.cpp25
-rw-r--r--lib/Parse/ParseTemplate.cpp7
-rw-r--r--lib/Parse/Parser.cpp98
-rw-r--r--lib/Sema/ParseAST.cpp8
-rw-r--r--lib/Sema/Sema.h31
-rw-r--r--lib/Sema/SemaDecl.cpp78
-rw-r--r--lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--lib/Sema/SemaDeclObjC.cpp23
-rw-r--r--lib/Sema/SemaStmt.cpp28
-rw-r--r--tools/clang-cc/ASTConsumers.cpp22
-rw-r--r--tools/clang-cc/AnalysisConsumer.cpp9
-rw-r--r--tools/clang-cc/Backend.cpp12
-rw-r--r--tools/clang-cc/PrintParserCallbacks.cpp20
-rw-r--r--tools/clang-cc/RewriteBlocks.cpp8
-rw-r--r--tools/clang-cc/RewriteObjC.cpp10
-rw-r--r--tools/clang-cc/SerializationTest.cpp5
-rw-r--r--tools/clang-cc/clang.cpp3
32 files changed, 347 insertions, 323 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 70daebf197..cafeecbae4 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -16,7 +16,7 @@
namespace clang {
class ASTContext;
- class Decl;
+ class DeclGroupRef;
class TagDecl;
class HandleTagDeclDefinition;
@@ -25,7 +25,7 @@ namespace clang {
/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
class ASTConsumer {
public:
- virtual ~ASTConsumer();
+ virtual ~ASTConsumer() {}
/// Initialize - This is called to initialize the consumer, providing the
/// ASTContext.
@@ -35,7 +35,7 @@ public:
/// called by the parser to process every top-level Decl*. Note that D can
/// be the head of a chain of Decls (e.g. for `int a, b` the chain will have
/// two elements). Use Decl::getNextDeclarator() to walk the chain.
- virtual void HandleTopLevelDecl(Decl *D) {}
+ virtual void HandleTopLevelDecl(DeclGroupRef D);
/// HandleTranslationUnit - This method is called when the ASTs for entire
/// translation unit have been parsed.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index aaec16ee44..abdb10dcbc 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -100,16 +100,9 @@ public:
};
private:
- /// NextDeclarator - If this decl was part of a multi-declarator declaration,
- /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
- Decl *NextDeclarator;
-
/// NextDeclInContext - The next declaration within the same lexical
/// DeclContext. These pointers form the linked list that is
/// traversed via DeclContext's decls_begin()/decls_end().
- /// FIXME: If NextDeclarator is non-NULL, will it always be the same
- /// as NextDeclInContext? If so, we can use a
- /// PointerIntPair<Decl*, 1> to make Decl smaller.
Decl *NextDeclInContext;
friend class DeclContext;
@@ -176,8 +169,7 @@ protected:
friend class CXXClassMemberWrapper;
Decl(Kind DK, DeclContext *DC, SourceLocation L)
- : NextDeclarator(0), NextDeclInContext(0),
- DeclCtx(DC),
+ : NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)), Access(AS_none) {
@@ -276,13 +268,6 @@ public:
void setLexicalDeclContext(DeclContext *DC);
- /// getNextDeclarator - If this decl was part of a multi-declarator
- /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
- /// declarator. Otherwise it returns null.
- Decl *getNextDeclarator() { return NextDeclarator; }
- const Decl *getNextDeclarator() const { return NextDeclarator; }
- void setNextDeclarator(Decl *N) { NextDeclarator = N; }
-
// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
// scoped decl is defined outside the current function or method. This is
// roughly global variables and functions, but also handles enums (which could
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index b1c2575361..1a8546339b 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -34,7 +34,7 @@ private:
DeclGroup(unsigned numdecls, Decl** decls);
public:
- static DeclGroup* Create(ASTContext& C, unsigned numdecls, Decl** decls);
+ static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
void Destroy(ASTContext& C);
unsigned size() const { return NumDecls; }
@@ -57,6 +57,8 @@ public:
};
class DeclGroupRef {
+ // Note this is not a PointerIntPair because we need the address of the
+ // non-group case to be valid as a Decl** for iteration.
enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
Decl* D;
@@ -71,6 +73,14 @@ public:
explicit DeclGroupRef(DeclGroup* dg)
: D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
+ static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
+ if (NumDecls == 0)
+ return DeclGroupRef();
+ if (NumDecls == 1)
+ return DeclGroupRef(Decls[0]);
+ return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
+ }
+
typedef Decl** iterator;
typedef Decl* const * const_iterator;
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 84023d6678..a58fc81c83 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -71,6 +71,7 @@ public:
typedef ActionBase::ExprTy ExprTy;
typedef ActionBase::StmtTy StmtTy;
typedef OpaquePtr<0> DeclPtrTy;
+ typedef OpaquePtr<1> DeclGroupPtrTy;
typedef void TypeTy; // FIXME: Change TypeTy to use OpaquePtr<1>.
typedef void AttrTy;
typedef void BaseTy;
@@ -130,6 +131,13 @@ public:
// Declaration Tracking Callbacks.
//===--------------------------------------------------------------------===//
+ /// ConvertDeclToDeclGroup - If the parser has one decl in a context where it
+ /// needs a decl group, it calls this to convert between the two
+ /// representations.
+ virtual DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
+ return DeclGroupPtrTy();
+ }
+
/// getTypeName - Return non-null if the specified identifier is a type name
/// in the current scope.
/// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or
@@ -210,11 +218,7 @@ public:
/// 'Init' specifies the initializer if any. This is for things like:
/// "int X = 4" or "typedef int foo".
///
- /// LastInGroup is non-null for cases where one declspec has multiple
- /// declarators on it. For example in 'int A, B', ActOnDeclarator will be
- /// called with LastInGroup=A when invoked for B.
- virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
- DeclPtrTy LastInGroup) {
+ virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
return DeclPtrTy();
}
@@ -253,10 +257,12 @@ public:
/// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
/// gives the actions implementation a chance to process the group as a whole.
- virtual DeclPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy Group) {
- return Group;
+ virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
+ unsigned NumDecls) {
+ return DeclGroupPtrTy();
}
+
/// @brief Indicates that all K&R-style parameter declarations have
/// been parsed prior to a function definition.
/// @param S The function prototype scope.
@@ -270,7 +276,7 @@ public:
virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
// Default to ActOnDeclarator.
return ActOnStartOfFunctionDef(FnBodyScope,
- ActOnDeclarator(FnBodyScope, D,DeclPtrTy()));
+ ActOnDeclarator(FnBodyScope, D));
}
/// ActOnStartOfFunctionDef - This is called at the start of a function
@@ -415,7 +421,8 @@ public:
bool isStmtExpr) {
return StmtEmpty();
}
- virtual OwningStmtResult ActOnDeclStmt(DeclPtrTy Decl,SourceLocation StartLoc,
+ virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+ SourceLocation StartLoc,
SourceLocation EndLoc) {
return StmtEmpty();
}
@@ -1041,8 +1048,7 @@ public:
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
Declarator &D,
ExprTy *BitfieldWidth,
- ExprTy *Init,
- DeclPtrTy LastInGroup) {
+ ExprTy *Init) {
return DeclPtrTy();
}
@@ -1408,9 +1414,8 @@ public:
unsigned allNum = 0,
DeclPtrTy *allProperties = 0,
unsigned pNum = 0,
- DeclPtrTy *allTUVars = 0,
+ DeclGroupPtrTy *allTUVars = 0,
unsigned tuvNum = 0) {
- return;
}
// ActOnProperty - called to build one property AST
virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
@@ -1570,8 +1575,7 @@ public:
/// ActOnDeclarator - If this is a typedef declarator, we modify the
/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
/// popped.
- virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
- DeclPtrTy LastInGroup);
+ virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D);
/// ActOnPopScope - When a scope is popped, if any typedefs are now
/// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 66058ca225..eb820570b9 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -120,6 +120,7 @@ public:
typedef Action::ExprTy ExprTy;
typedef Action::StmtTy StmtTy;
typedef Action::DeclPtrTy DeclPtrTy;
+ typedef Action::DeclGroupPtrTy DeclGroupPtrTy;
typedef Action::TypeTy TypeTy;
typedef Action::BaseTy BaseTy;
typedef Action::MemInitTy MemInitTy;
@@ -167,7 +168,7 @@ public:
/// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
/// the EOF was encountered.
- bool ParseTopLevelDecl(DeclPtrTy &Result);
+ bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
private:
//===--------------------------------------------------------------------===//
@@ -547,8 +548,8 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
- DeclPtrTy ParseExternalDeclaration();
- DeclPtrTy ParseDeclarationOrFunctionDefinition(
+ DeclGroupPtrTy ParseExternalDeclaration();
+ DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
TemplateParameterLists *TemplateParams = 0,
AccessSpecifier AS = AS_none);
@@ -807,9 +808,9 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.7: Declarations.
- DeclPtrTy ParseDeclaration(unsigned Context);
- DeclPtrTy ParseSimpleDeclaration(unsigned Context);
- DeclPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
+ DeclGroupPtrTy ParseDeclaration(unsigned Context);
+ DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context);
+ DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
void ParseDeclarationSpecifiers(DeclSpec &DS,
TemplateParameterLists *TemplateParams = 0,
@@ -1009,7 +1010,7 @@ private:
AccessSpecifier AS = AS_none);
void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
DeclPtrTy TagDecl);
- DeclPtrTy ParseCXXClassMemberDeclaration(AccessSpecifier AS);
+ void ParseCXXClassMemberDeclaration(AccessSpecifier AS);
void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
index 6c44d1ab7b..f37cbdea54 100644
--- a/lib/AST/ASTConsumer.cpp
+++ b/lib/AST/ASTConsumer.cpp
@@ -12,7 +12,8 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
using namespace clang;
-ASTConsumer::~ASTConsumer() {}
+void ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {}
+
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index 36a7c2b400..64b0399901 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -19,13 +19,12 @@
#include "llvm/Bitcode/Deserialize.h"
using namespace clang;
-DeclGroup* DeclGroup::Create(ASTContext& C, unsigned numdecls, Decl** decls) {
- assert (numdecls > 0);
- unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * numdecls;
- unsigned alignment = llvm::AlignOf<DeclGroup>::Alignment;
- void* mem = C.Allocate(size, alignment);
- new (mem) DeclGroup(numdecls, decls);
- return static_cast<DeclGroup*>(mem);
+DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
+ assert(NumDecls > 1 && "Invalid DeclGroup");
+ unsigned Size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
+ void* Mem = C.Allocate(Size, llvm::AlignOf<DeclGroup>::Alignment);
+ new (Mem) DeclGroup(NumDecls, Decls);
+ return static_cast<DeclGroup*>(Mem);
}
/// Emit - Serialize a DeclGroup to Bitcode.
@@ -37,9 +36,9 @@ void DeclGroup::Emit(llvm::Serializer& S) const {
/// Read - Deserialize a DeclGroup from Bitcode.
DeclGroup* DeclGroup::Read(llvm::Deserializer& D, ASTContext& C) {
unsigned NumDecls = (unsigned) D.ReadInt();
- unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
+ unsigned Size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls;
unsigned alignment = llvm::AlignOf<DeclGroup>::Alignment;
- DeclGroup* DG = (DeclGroup*) C.Allocate(size, alignment);
+ DeclGroup* DG = (DeclGroup*) C.Allocate(Size, alignment);
new (DG) DeclGroup();
DG->NumDecls = NumDecls;
D.BatchReadOwnedPtrs(NumDecls, &(*DG)[0], C);
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index 8e3ef08d2c..acaced2468 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -39,7 +39,6 @@ void Decl::Emit(Serializer& S) const {
S.EmitInt(Access);
S.EmitPtr(cast_or_null<Decl>(getDeclContext())); // From Decl.
S.EmitPtr(cast_or_null<Decl>(getLexicalDeclContext())); // From Decl.
- S.EmitPtr(NextDeclarator);
if (const DeclContext *DC = dyn_cast<const DeclContext>(this))
DC->EmitOutRec(S);
@@ -144,7 +143,6 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) {
D.ReadPtr(MDC->SemanticDC, SemaDCPtrID);
D.ReadPtr(MDC->LexicalDC, LexicalDCPtrID);
}
- D.ReadPtr(Dcl->NextDeclarator);
if (DeclContext *DC = dyn_cast<DeclContext>(Dcl))
DC->ReadOutRec(D, C);
bool OwnsNext = D.ReadBool();
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 94829c01e3..20024f513f 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -67,12 +67,11 @@ void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
if (inDecl()) {
assert (decl);
+ // FIXME: SIMPLIFY AWAY.
if (ImmediateAdvance)
- decl = decl->getNextDeclarator();
-
- for ( ; decl ; decl = decl->getNextDeclarator())
- if (HandleDecl(decl))
- return;
+ decl = 0;
+ else if (HandleDecl(decl))
+ return;
}
else {
assert (inDeclGroup());
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index d41f1339b0..896464ed5a 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -60,16 +60,16 @@ namespace {
*M, *TD, Diags));
}
- virtual void HandleTopLevelDecl(Decl *D) {
+ virtual void HandleTopLevelDecl(DeclGroupRef DG) {
// Make sure to emit all elements of a Decl.
- for (; D; D = D->getNextDeclarator())
- Builder->EmitTopLevelDecl(D);
+ for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
+ Builder->EmitTopLevelDecl(*I);
}
/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
- /// (e.g. struct, union, enum, class) is completed. This allows the client to
- /// hack on the type, which can occur at any point in the file (because these
- /// can be defined in declspecs).
+ /// to (e.g. struct, union, enum, class) is completed. This allows the
+ /// client hack on the type, which can occur at any point in the file
+ /// (because these can be defined in declspecs).
virtual void HandleTagDeclDefinition(TagDecl *D) {
Builder->UpdateCompletedType(D);
}
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
index 049228f56c..f31aef61d3 100644
--- a/lib/Parse/MinimalAction.cpp
+++ b/lib/Parse/MinimalAction.cpp
@@ -144,7 +144,7 @@ MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
/// popped.
Action::DeclPtrTy
-MinimalAction::ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy LastInGroup) {
+MinimalAction::ActOnDeclarator(Scope *S, Declarator &D) {
IdentifierInfo *II = D.getIdentifier();
// If there is no identifier associated with this declarator, bail out.
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index e139cf9c3e..45eaa74681 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -27,8 +27,7 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon)) &&
"Current token not a '{' or ':'!");
- DeclPtrTy FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0,
- DeclPtrTy());
+ DeclPtrTy FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0);
// Consume the tokens and store them for later parsing.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5a8b2b8569..1f8522f094 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -228,27 +228,36 @@ void Parser::FuzzyParseMicrosoftDeclSpec() {
/// [C++0x] static_assert-declaration
/// others... [FIXME]
///
-Parser::DeclPtrTy Parser::ParseDeclaration(unsigned Context) {
+Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context) {
+ DeclPtrTy SingleDecl;
switch (Tok.getKind()) {
case tok::kw_export:
case tok::kw_template:
- return ParseTemplateDeclarationOrSpecialization(Context);
+ SingleDecl = ParseTemplateDeclarationOrSpecialization(Context);
+ break;
case tok::kw_namespace:
- return ParseNamespace(Context);
+ SingleDecl = ParseNamespace(Context);
+ break;
case tok::kw_using:
- return ParseUsingDirectiveOrDeclaration(Context);
+ SingleDecl = ParseUsingDirectiveOrDeclaration(Context);
+ break;
case tok::kw_static_assert:
- return ParseStaticAssertDeclaration();
+ SingleDecl = ParseStaticAssertDeclaration();
+ break;
default:
return ParseSimpleDeclaration(Context);
}
+
+ // This routine returns a DeclGroup, if the thing we parsed only contains a
+ // single decl, convert it now.
+ return Actions.ConvertDeclToDeclGroup(SingleDecl);
}
/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
/// declaration-specifiers init-declarator-list[opt] ';'
///[C90/C++]init-declarator-list ';' [TODO]
/// [OMP] threadprivate-directive [TODO]
-Parser::DeclPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
+Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
// Parse the common declaration-specifiers piece.
DeclSpec DS;
ParseDeclarationSpecifiers(DS);
@@ -257,7 +266,8 @@ Parser::DeclPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
// declaration-specifiers init-declarator-list[opt] ';'
if (Tok.is(tok::semi)) {
ConsumeToken();
- return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+ DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+ return Actions.ConvertDeclToDeclGroup(TheDecl);
}
Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
@@ -291,12 +301,11 @@ Parser::DeclPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
/// According to the standard grammar, =default and =delete are function
/// definitions, but that definitely doesn't fit with the parser here.
///
-Parser::DeclPtrTy Parser::
+Parser::DeclGroupPtrTy Parser::
ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
-
- // Declarators may be grouped together ("int X, *Y, Z();"). Provide info so
- // that they can be chained properly if the actions want this.
- Parser::DeclPtrTy LastDeclInGroup;
+ // Declarators may be grouped together ("int X, *Y, Z();"). Remember the decls
+ // that we parse together here.
+ llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
// At this point, we know that it is not a function definition. Parse the
// rest of the init-declarator-list.
@@ -307,7 +316,7 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi);
- return DeclPtrTy();
+ return DeclGroupPtrTy();
}
D.setAsmLabel(AsmLabel.release());
@@ -322,21 +331,22 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
}
// Inform the current actions module that we just parsed this declarator.
- LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
+ DeclPtrTy ThisDecl = Actions.ActOnDeclarator(CurScope, D);
+ DeclsInGroup.push_back(ThisDecl);
// Parse declarator '=' initializer.
if (Tok.is(tok::equal)) {
ConsumeToken();
if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
SourceLocation DelLoc = ConsumeToken();
- Actions.SetDeclDeleted(LastDeclInGroup, DelLoc);
+ Actions.SetDeclDeleted(ThisDecl, DelLoc);
} else {
OwningExprResult Init(ParseInitializer());
if (Init.isInvalid()) {
SkipUntil(tok::semi);
- return DeclPtrTy();
+ return DeclGroupPtrTy();
}
- Actions.AddInitializerToDecl(LastDeclInGroup, move(Init));
+ Actions.AddInitializerToDecl(ThisDecl, move(Init));
}
} else if (Tok.is(tok::l_paren)) {
// Parse C++ direct initializer: '(' expression-list ')'
@@ -355,12 +365,12 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
if (!InvalidExpr) {
assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
"Unexpected number of commas!");
- Actions.AddCXXDirectInitializerToDecl(LastDeclInGroup, LParenLoc,
+ Actions.AddCXXDirectInitializerToDecl(ThisDecl, LParenLoc,
move_arg(Exprs),
&CommaLocs[0], RParenLoc);
}
} else {
- Actions.ActOnUninitializedDecl(LastDeclInGroup);
+ Actions.ActOnUninitializedDecl(ThisDecl);
}
// If we don't have a comma, it is either the end of the list (a ';') or an
@@ -395,23 +405,26 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
// for(is key; in keys) is error.
if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) {
Diag(Tok, diag::err_parse_error);
- return DeclPtrTy();
+ return DeclGroupPtrTy();
}
- return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
+
+ return Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0],
+ DeclsInGroup.size());
}
// If this is an ObjC2 for-each loop, this is a successful declarator
// parse. The syntax for these looks like:
// 'for' '(' declaration 'in' expr ')' statement
if (D.getContext() == Declarator::ForContext && isTokIdentifier_in())
- return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
+ return Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0],
+ DeclsInGroup.size());
Diag(Tok, diag::err_parse_error);
// Skip to end of block or statement
SkipUntil(tok::r_brace, true, true);
if (Tok.is(tok::semi))
ConsumeToken();
- return DeclPtrTy();
+ return DeclGroupPtrTy();
}
/// ParseSpecifierQualifierList
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index c50a033e56..37a460cd41 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -663,14 +663,17 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const
/// constant-initializer:
/// '=' constant-expression
///
-Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
+void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// static_assert-declaration
- if (Tok.is(tok::kw_static_assert))
- return ParseStaticAssertDeclaration();
+ if (Tok.is(tok::kw_static_assert)) {
+ ParseStaticAssertDeclaration();
+ return;
+ }
- if (Tok.is(tok::kw_template))
- return ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext,
- AS);
+ if (Tok.is(tok::kw_template)) {
+ ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext, AS);
+ return;
+ }
// Handle: member-declaration ::= '__extension__' member-declaration
if (Tok.is(tok::kw___extension__)) {
@@ -692,14 +695,15 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// class-specifier or an enum-specifier or in a friend declaration.
// FIXME: Friend declarations.
switch (DS.getTypeSpecType()) {
- case DeclSpec::TST_struct:
- case DeclSpec::TST_union:
- case DeclSpec::TST_class:
- case DeclSpec::TST_enum:
- return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
- default:
- Diag(DSStart, diag::err_no_declarators);
- return DeclPtrTy();
+ case DeclSpec::TST_struct:
+ case DeclSpec::TST_union:
+ case DeclSpec::TST_class:
+ case DeclSpec::TST_enum:
+ Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+ return;
+ default:
+ Diag(DSStart, diag::err_no_declarators);
+ return;
}
}
@@ -714,7 +718,7 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
SkipUntil(tok::r_brace, true);
if (Tok.is(tok::semi))
ConsumeToken();
- return DeclPtrTy();
+ return;
}
// function-definition:
@@ -724,7 +728,7 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Diag(Tok, diag::err_func_def_no_params);
ConsumeBrace();
SkipUntil(tok::r_brace, true);
- return DeclPtrTy();
+ return;
}
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
@@ -734,10 +738,11 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// assumes the declarator represents a function, not a typedef.
ConsumeBrace();
SkipUntil(tok::r_brace, true);
- return DeclPtrTy();
+ return;
}
- return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
+ ParseCXXInlineMethodDef(AS, DeclaratorInfo);
+ return;
}
}
@@ -745,7 +750,7 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// member-declarator
// member-declarator-list ',' member-declarator
- DeclPtrTy LastDeclInGroup;
+ llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
OwningExprResult BitfieldSize(Actions);
OwningExprResult Init(Actions);
@@ -784,14 +789,14 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
}
// NOTE: If Sema is the Action module and declarator is an instance field,
- // this call will *not* return the created decl; LastDeclInGroup will be
- // returned instead.
+ // this call will *not* return the created decl; It will return null.
// See Sema::ActOnCXXMemberDeclarator for details.
- LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
- DeclaratorInfo,
- BitfieldSize.release(),
- Init.release(),
- LastDeclInGroup);
+ DeclPtrTy ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
+ DeclaratorInfo,
+ BitfieldSize.release(),
+ Init.release());
+ if (ThisDecl)
+ DeclsInGroup.push_back(ThisDecl);
if (DeclaratorInfo.isFunctionDeclarator() &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec()
@@ -807,7 +812,7 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// Push this method onto the stack of late-parsed method
// declarations.
getCurTopClassStack().MethodDecls.push_back(
- LateParsedMethodDeclaration(LastDeclInGroup));
+ LateParsedMethodDeclaration(ThisDecl));
LateMethod = &getCurTopClassStack().MethodDecls.back();
// Add all of the parameters prior t