mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
Push DeclGroup much farther throughout the compiler. Now the various
productions (except the already broken ObjC cases like @class X,Y;) in the parser that can produce more than one Decl return a DeclGroup instead of a Decl, etc. This allows elimination of the Decl::NextDeclarator field, and exposes various clients that should look at all decls in a group, but which were only looking at one (such as the dumper, printer, etc). These have been fixed. Still TODO: 1) there are some FIXME's in the code about potentially using DeclGroup for better location info. 2) ParseObjCAtDirectives should return a DeclGroup due to @class etc. 3) I'm not sure what is going on with StmtIterator.cpp, or if it can be radically simplified now. 4) I put a truly horrible hack in ParseTemplate.cpp. I plan to bring up #3/4 on the mailing list, but don't plan to tackle #1/2 in the short term. llvm-svn: 68002
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 to this one (they don't
|
||||
@@ -853,8 +858,9 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||
|
||||
if (Tok.is(tok::semi)) {
|
||||
ConsumeToken();
|
||||
// Reverse the chain list.
|
||||
return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
|
||||
Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0],
|
||||
DeclsInGroup.size());
|
||||
return;
|
||||
}
|
||||
|
||||
Diag(Tok, diag::err_expected_semi_decl_list);
|
||||
@@ -862,7 +868,7 @@ Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||
SkipUntil(tok::r_brace, true, true);
|
||||
if (Tok.is(tok::semi))
|
||||
ConsumeToken();
|
||||
return DeclPtrTy();
|
||||
return;
|
||||
}
|
||||
|
||||
/// ParseCXXMemberSpecification - Parse the class definition.
|
||||
|
||||
@@ -215,7 +215,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
||||
tok::ObjCKeywordKind contextKey) {
|
||||
llvm::SmallVector<DeclPtrTy, 32> allMethods;
|
||||
llvm::SmallVector<DeclPtrTy, 16> allProperties;
|
||||
llvm::SmallVector<DeclPtrTy, 8> allTUVariables;
|
||||
llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables;
|
||||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
|
||||
|
||||
SourceLocation AtEndLoc;
|
||||
@@ -253,8 +253,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
||||
|
||||
// FIXME: as the name implies, this rule allows function definitions.
|
||||
// We could pass a flag or check for functions during semantic analysis.
|
||||
DeclPtrTy VFDecl = ParseDeclarationOrFunctionDefinition();
|
||||
allTUVariables.push_back(VFDecl);
|
||||
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -359,13 +358,9 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
||||
// Insert collected methods declarations into the @interface object.
|
||||
// This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
|
||||
Actions.ActOnAtEnd(AtEndLoc, interfaceDecl,
|
||||
allMethods.empty() ? 0 : &allMethods[0],
|
||||
allMethods.size(),
|
||||
allProperties.empty() ? 0 : &allProperties[0],
|
||||
allProperties.size(),
|
||||
allTUVariables.empty() ? 0 :
|
||||
&allTUVariables[0],
|
||||
allTUVariables.size());
|
||||
&allMethods[0], allMethods.size(),
|
||||
&allProperties[0], allProperties.size(),
|
||||
&allTUVariables[0], allTUVariables.size());
|
||||
}
|
||||
|
||||
/// Parse property attribute declarations.
|
||||
|
||||
@@ -101,7 +101,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
||||
default: {
|
||||
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
|
||||
SourceLocation DeclStart = Tok.getLocation();
|
||||
DeclPtrTy Decl = ParseDeclaration(Declarator::BlockContext);
|
||||
DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext);
|
||||
// FIXME: Pass in the right location for the end of the declstmt.
|
||||
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
|
||||
}
|
||||
@@ -444,7 +444,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||
if (isDeclarationStatement()) {
|
||||
// FIXME: Save the __extension__ on the decl as a node somehow.
|
||||
SourceLocation DeclStart = Tok.getLocation();
|
||||
DeclPtrTy Res = ParseDeclaration(Declarator::BlockContext);
|
||||
DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext);
|
||||
// FIXME: Pass in the right location for the end of the declstmt.
|
||||
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
|
||||
} else {
|
||||
@@ -912,10 +912,9 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
|
||||
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
|
||||
|
||||
SourceLocation DeclStart = Tok.getLocation();
|
||||
DeclPtrTy aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
|
||||
DeclGroupPtrTy VarDecls = ParseSimpleDeclaration(Declarator::ForContext);
|
||||
// FIXME: Pass in the right location for the end of the declstmt.
|
||||
FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
|
||||
DeclStart);
|
||||
FirstPart = Actions.ActOnDeclStmt(VarDecls, DeclStart, DeclStart);
|
||||
if ((ForEach = isTokIdentifier_in())) {
|
||||
ConsumeToken(); // consume 'in'
|
||||
SecondPart = ParseExpression();
|
||||
@@ -929,12 +928,10 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
|
||||
|
||||
if (Tok.is(tok::semi)) {
|
||||
ConsumeToken();
|
||||
}
|
||||
else if ((ForEach = isTokIdentifier_in())) {
|
||||
} else if ((ForEach = isTokIdentifier_in())) {
|
||||
ConsumeToken(); // consume 'in'
|
||||
SecondPart = ParseExpression();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
|
||||
SkipUntil(tok::semi);
|
||||
}
|
||||
@@ -995,11 +992,11 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
|
||||
return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart),
|
||||
move(SecondPart), move(ThirdPart),
|
||||
RParenLoc, move(Body));
|
||||
else
|
||||
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
|
||||
move(FirstPart),
|
||||
move(SecondPart),
|
||||
RParenLoc, move(Body));
|
||||
|
||||
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
|
||||
move(FirstPart),
|
||||
move(SecondPart),
|
||||
RParenLoc, move(Body));
|
||||
}
|
||||
|
||||
/// ParseGotoStatement
|
||||
|
||||
@@ -94,7 +94,12 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
|
||||
} while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template));
|
||||
|
||||
// Parse the actual template declaration.
|
||||
return ParseDeclarationOrFunctionDefinition(&ParamLists, AS);
|
||||
|
||||
// FIXME: This accepts template<typename x> int y;
|
||||
// FIXME: Converting DeclGroupPtr to DeclPtr like this is an insanely gruesome
|
||||
// hack, will bring up on cfe-dev.
|
||||
DeclGroupPtrTy DG = ParseDeclarationOrFunctionDefinition(&ParamLists, AS);
|
||||
return DeclPtrTy::make(DG.get());
|
||||
}
|
||||
|
||||
/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
|
||||
|
||||
@@ -324,8 +324,8 @@ void Parser::Initialize() {
|
||||
|
||||
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
|
||||
/// action tells us to. This returns true if the EOF was encountered.
|
||||
bool Parser::ParseTopLevelDecl(DeclPtrTy &Result) {
|
||||
Result = DeclPtrTy();
|
||||
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
|
||||
Result = DeclGroupPtrTy();
|
||||
if (Tok.is(tok::eof)) {
|
||||
Actions.ActOnEndOfTranslationUnit();
|
||||
return true;
|
||||
@@ -342,7 +342,7 @@ bool Parser::ParseTopLevelDecl(DeclPtrTy &Result) {
|
||||
void Parser::ParseTranslationUnit() {
|
||||
Initialize();
|
||||
|
||||
DeclPtrTy Res;
|
||||
DeclGroupPtrTy Res;
|
||||
while (!ParseTopLevelDecl(Res))
|
||||
/*parse them all*/;
|
||||
|
||||
@@ -368,20 +368,21 @@ void Parser::ParseTranslationUnit() {
|
||||
/// [GNU] asm-definition:
|
||||
/// simple-asm-expr ';'
|
||||
///
|
||||
Parser::DeclPtrTy Parser::ParseExternalDeclaration() {
|
||||
Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() {
|
||||
DeclPtrTy SingleDecl;
|
||||
switch (Tok.getKind()) {
|
||||
case tok::semi:
|
||||
Diag(Tok, diag::ext_top_level_semi);
|
||||
ConsumeToken();
|
||||
// TODO: Invoke action for top-level semicolon.
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::r_brace:
|
||||
Diag(Tok, diag::err_expected_external_declaration);
|
||||
ConsumeBrace();
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::eof:
|
||||
Diag(Tok, diag::err_expected_external_declaration);
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::kw___extension__: {
|
||||
// __extension__ silences extension warnings in the subexpression.
|
||||
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
||||
@@ -394,20 +395,26 @@ Parser::DeclPtrTy Parser::ParseExternalDeclaration() {
|
||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
||||
"top-level asm block");
|
||||
|
||||
if (!Result.isInvalid())
|
||||
return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
|
||||
return DeclPtrTy();
|
||||
if (Result.isInvalid())
|
||||
return DeclGroupPtrTy();
|
||||
SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
|
||||
break;
|
||||
}
|
||||
case tok::at:
|
||||
// @ is not a legal token unless objc is enabled, no need to check.
|
||||
return ParseObjCAtDirectives();
|
||||
// @ is not a legal token unless objc is enabled, no need to check for ObjC.
|
||||
/// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like
|
||||
/// @class foo, bar;
|
||||
SingleDecl = ParseObjCAtDirectives();
|
||||
break;
|
||||
case tok::minus:
|
||||
case tok::plus:
|
||||
if (getLang().ObjC1)
|
||||
return ParseObjCMethodDefinition();
|
||||
Diag(Tok, diag::err_expected_external_declaration);
|
||||
ConsumeToken();
|
||||
return DeclPtrTy();
|
||||
if (!getLang().ObjC1) {
|
||||
Diag(Tok, diag::err_expected_external_declaration);
|
||||
ConsumeToken();
|
||||
return DeclGroupPtrTy();
|
||||
}
|
||||
SingleDecl = ParseObjCMethodDefinition();
|
||||
break;
|
||||
case tok::kw_using:
|
||||
case tok::kw_namespace:
|
||||
case tok::kw_typedef:
|
||||
@@ -420,6 +427,10 @@ Parser::DeclPtrTy Parser::ParseExternalDeclaration() {
|
||||
// We can't tell whether this is a function-definition or declaration yet.
|
||||
return ParseDeclarationOrFunctionDefinition();
|
||||
}
|
||||
|
||||
// This routine returns a DeclGroup, if the thing we parsed only contains a
|
||||
// single decl, convert it now.
|
||||
return Actions.ConvertDeclToDeclGroup(SingleDecl);
|
||||
}
|
||||
|
||||
/// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
|
||||
@@ -438,7 +449,7 @@ Parser::DeclPtrTy Parser::ParseExternalDeclaration() {
|
||||
/// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
|
||||
/// [OMP] threadprivate-directive [TODO]
|
||||
///
|
||||
Parser::DeclPtrTy
|
||||
Parser::DeclGroupPtrTy
|
||||
Parser::ParseDeclarationOrFunctionDefinition(
|
||||
TemplateParameterLists *TemplateParams,
|
||||
AccessSpecifier AS) {
|
||||
@@ -450,7 +461,8 @@ Parser::ParseDeclarationOrFunctionDefinition(
|
||||
// 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);
|
||||
}
|
||||
|
||||
// ObjC2 allows prefix attributes on class interfaces and protocols.
|
||||
@@ -462,14 +474,18 @@ Parser::ParseDeclarationOrFunctionDefinition(
|
||||
!Tok.isObjCAtKeyword(tok::objc_protocol)) {
|
||||
Diag(Tok, diag::err_objc_unexpected_attr);
|
||||
SkipUntil(tok::semi); // FIXME: better skip?
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
}
|
||||
const char *PrevSpec = 0;
|
||||
if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec))
|
||||
Diag(AtLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
|
||||
|
||||
DeclPtrTy TheDecl;
|
||||
if (Tok.isObjCAtKeyword(tok::objc_protocol))
|
||||
return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
|
||||
return ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
|
||||
TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
|
||||
else
|
||||
TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
|
||||
return Actions.ConvertDeclToDeclGroup(TheDecl);
|
||||
}
|
||||
|
||||
// If the declspec consisted only of 'extern' and we have a string
|
||||
@@ -477,8 +493,10 @@ Parser::ParseDeclarationOrFunctionDefinition(
|
||||
// 'extern "C"'.
|
||||
if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
|
||||
DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
|
||||
DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier)
|
||||
return ParseLinkage(Declarator::FileContext);
|
||||
DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
|
||||
DeclPtrTy TheDecl = ParseLinkage(Declarator::FileContext);
|
||||
return Actions.ConvertDeclToDeclGroup(TheDecl);
|
||||
}
|
||||
|
||||
// Parse the first declarator.
|
||||
Declarator DeclaratorInfo(DS, Declarator::FileContext);
|
||||
@@ -489,7 +507,7 @@ Parser::ParseDeclarationOrFunctionDefinition(
|
||||
SkipUntil(tok::r_brace, true, true);
|
||||
if (Tok.is(tok::semi))
|
||||
ConsumeToken();
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
}
|
||||
|
||||
// If the declarator is the start of a function definition, handle it.
|
||||
@@ -500,8 +518,12 @@ Parser::ParseDeclarationOrFunctionDefinition(
|
||||
Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
|
||||
(getLang().CPlusPlus &&
|
||||
Tok.is(tok::l_paren)) ) { // int X(0) -> not a function def [C++]
|
||||
// FALL THROUGH.
|
||||
} else if (DeclaratorInfo.isFunctionDeclarator() &&
|
||||
// Parse the init-declarator-list for a normal declaration.
|
||||
return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
|
||||
}
|
||||
|
||||
|
||||
if (DeclaratorInfo.isFunctionDeclarator() &&
|
||||
(Tok.is(tok::l_brace) || // int X() {}
|
||||
(!getLang().CPlusPlus &&
|
||||
isDeclarationSpecifier()) || // int X(f) int f; {}
|
||||
@@ -519,20 +541,18 @@ Parser::ParseDeclarationOrFunctionDefinition(
|
||||
} else {
|
||||
SkipUntil(tok::semi);
|
||||
}
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
}
|
||||
return ParseFunctionDefinition(DeclaratorInfo);
|
||||
} else {
|
||||
if (DeclaratorInfo.isFunctionDeclarator())
|
||||
Diag(Tok, diag::err_expected_fn_body);
|
||||
else
|
||||
Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
|
||||
SkipUntil(tok::semi);
|
||||
return DeclPtrTy();
|
||||
DeclPtrTy TheDecl = ParseFunctionDefinition(DeclaratorInfo);
|
||||
return Actions.ConvertDeclToDeclGroup(TheDecl);
|
||||
}
|
||||
|
||||
// Parse the init-declarator-list for a normal declaration.
|
||||
return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
|
||||
|
||||
if (DeclaratorInfo.isFunctionDeclarator())
|
||||
Diag(Tok, diag::err_expected_fn_body);
|
||||
else
|
||||
Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
|
||||
SkipUntil(tok::semi);
|
||||
return DeclGroupPtrTy();
|
||||
}
|
||||
|
||||
/// ParseFunctionDefinition - We parsed and verified that the specified
|
||||
|
||||
@@ -44,16 +44,14 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
|
||||
|
||||
Consumer->Initialize(Ctx);
|
||||
|
||||
Parser::DeclPtrTy ADecl;
|
||||
Parser::DeclGroupPtrTy ADecl;
|
||||
|
||||
while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file.
|
||||
// If we got a null return and something *was* parsed, ignore it. This
|
||||
// is due to a top-level semicolon, an action override, or a parse error
|
||||
// skipping something.
|
||||
if (ADecl) {
|
||||
Decl *D = ADecl.getAs<Decl>();
|
||||
Consumer->HandleTopLevelDecl(D);
|
||||
}
|
||||
if (ADecl)
|
||||
Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
|
||||
};
|
||||
|
||||
Consumer->HandleTranslationUnit(Ctx);
|
||||
|
||||
@@ -328,29 +328,28 @@ public:
|
||||
/// an empty string if not. This is used for pretty crash reporting.
|
||||
virtual std::string getDeclName(DeclPtrTy D);
|
||||
|
||||
DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
|
||||
|
||||
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
|
||||
Scope *S, const CXXScopeSpec *SS);
|
||||
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
|
||||
DeclPtrTy LastInGroup){
|
||||
return ActOnDeclarator(S, D, LastInGroup, false);
|
||||
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
|
||||
return ActOnDeclarator(S, D, false);
|
||||
}
|
||||
DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy LastInGroup,
|
||||
bool IsFunctionDefinition);
|
||||
DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition);
|
||||
void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
|
||||
Scope *S);
|
||||
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, Decl* LastDeclarator,
|
||||
QualType R,
|
||||
Decl* PrevDecl, bool& InvalidDecl,
|
||||
bool &Redeclaration);
|
||||
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, Decl* LastDeclarator,
|
||||
QualType R,
|
||||
NamedDecl* PrevDecl, bool& InvalidDecl,
|
||||
bool &Redeclaration);
|
||||
bool CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
||||
bool &Redeclaration);
|
||||
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, Decl *LastDeclarator,
|
||||
NamedDecl* PrevDecl,
|
||||
QualType R, NamedDecl* PrevDecl,
|
||||
bool IsFunctionDefinition,
|
||||
bool& InvalidDecl, bool &Redeclaration);
|
||||
bool CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
|
||||
@@ -367,8 +366,8 @@ public:
|
||||
void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
|
||||
void ActOnUninitializedDecl(DeclPtrTy dcl);
|
||||
virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
|
||||
virtual DeclPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy Group);
|
||||
|
||||
virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
|
||||
unsigned NumDecls);
|
||||
virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D);
|
||||
virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, Declarator &D);
|
||||
virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, DeclPtrTy D);
|
||||
@@ -490,8 +489,7 @@ public:
|
||||
Stmt* ParentCompoundStmt);
|
||||
|
||||
/// Subroutines of ActOnDeclarator().
|
||||
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
|
||||
Decl *LastDecl);
|
||||
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T);
|
||||
bool MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
||||
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
|
||||
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
|
||||
@@ -1084,7 +1082,7 @@ public:
|
||||
virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
|
||||
MultiStmtArg Elts,
|
||||
bool isStmtExpr);
|
||||
virtual OwningStmtResult ActOnDeclStmt(DeclPtrTy Decl,
|
||||
virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
|
||||
@@ -1589,8 +1587,7 @@ public:
|
||||
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
|
||||
Declarator &D,
|
||||
ExprTy *BitfieldWidth,
|
||||
ExprTy *Init,
|
||||
DeclPtrTy LastInGroup);
|
||||
ExprTy *Init);
|
||||
|
||||
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
|
||||
Scope *S,
|
||||
@@ -2076,7 +2073,7 @@ public:
|
||||
virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
|
||||
DeclPtrTy *allMethods = 0, unsigned allNum = 0,
|
||||
DeclPtrTy *allProperties = 0, unsigned pNum = 0,
|
||||
DeclPtrTy *allTUVars = 0, unsigned tuvNum = 0);
|
||||
DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
|
||||
|
||||
virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
|
||||
FieldDeclarator &FD, ObjCDeclSpec &ODS,
|
||||
|
||||
@@ -39,6 +39,10 @@ std::string Sema::getDeclName(DeclPtrTy d) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
|
||||
return DeclGroupPtrTy::make(DeclGroupRef(Ptr.getAs<Decl>()));
|
||||
}
|
||||
|
||||
/// \brief If the identifier refers to a type name within this scope,
|
||||
/// return the declaration of that type.
|
||||
///
|
||||
@@ -1235,10 +1239,7 @@ static bool isNearlyMatchingFunction(ASTContext &Context,
|
||||
}
|
||||
|
||||
Sema::DeclPtrTy
|
||||
Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy lastDecl,
|
||||
bool IsFunctionDefinition) {
|
||||
NamedDecl *LastDeclarator =
|
||||
dyn_cast_or_null<NamedDecl>(lastDecl.getAs<Decl>());
|
||||
Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
|
||||
DeclarationName Name = GetNameForDeclarator(D);
|
||||
|
||||
// All of these full declarators require an identifier. If it doesn't have
|
||||
@@ -1356,14 +1357,14 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy lastDecl,
|
||||
|
||||
bool Redeclaration = false;
|
||||
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
||||
New = ActOnTypedefDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
|
||||
New = ActOnTypedefDeclarator(S, D, DC, R, PrevDecl,
|
||||
InvalidDecl, Redeclaration);
|
||||
} else if (R->isFunctionType()) {
|
||||
New = ActOnFunctionDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
|
||||
New = ActOnFunctionDeclarator(S, D, DC, R, PrevDecl,
|
||||
IsFunctionDefinition, InvalidDecl,
|
||||
Redeclaration);
|
||||
} else {
|
||||
New = ActOnVariableDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
|
||||
New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl,
|
||||
InvalidDecl, Redeclaration);
|
||||
}
|
||||
|
||||
@@ -1454,8 +1455,7 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
|
||||
|
||||
NamedDecl*
|
||||
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, Decl* LastDeclarator,
|
||||
Decl* PrevDecl, bool& InvalidDecl,
|
||||
QualType R, Decl* PrevDecl, bool& InvalidDecl,
|
||||
bool &Redeclaration) {
|
||||
// Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
|
||||
if (D.getCXXScopeSpec().isSet()) {
|
||||
@@ -1475,7 +1475,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
diag::err_virtual_non_function);
|
||||
}
|
||||
|
||||
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, LastDeclarator);
|
||||
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R);
|
||||
if (!NewTD) return 0;
|
||||
|
||||
// Handle attributes prior to checking for duplicates in MergeVarDecl
|
||||
@@ -1580,8 +1580,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
|
||||
|
||||
NamedDecl*
|
||||
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, Decl* LastDeclarator,
|
||||
NamedDecl* PrevDecl, bool& InvalidDecl,
|
||||
QualType R,NamedDecl* PrevDecl, bool& InvalidDecl,
|
||||
bool &Redeclaration) {
|
||||
DeclarationName Name = GetNameForDeclarator(D);
|
||||
|
||||
@@ -1645,7 +1644,6 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
// FIXME: Move to DeclGroup...
|
||||
D.getDeclSpec().getSourceRange().getBegin());
|
||||
NewVD->setThreadSpecified(ThreadSpecified);
|
||||
NewVD->setNextDeclarator(LastDeclarator);
|
||||
|
||||
// Set the lexical context. If the declarator has a C++ scope specifier, the
|
||||
// lexical context will be different from the semantic context.
|
||||
@@ -1800,8 +1798,8 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
||||
|
||||
NamedDecl*
|
||||
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, Decl *LastDeclarator,
|
||||
NamedDecl* PrevDecl, bool IsFunctionDefinition,
|
||||
QualType R, NamedDecl* PrevDecl,
|
||||
bool IsFunctionDefinition,
|
||||
bool& InvalidDecl, bool &Redeclaration) {
|
||||
assert(R.getTypePtr()->isFunctionType());
|
||||
|
||||
@@ -1937,7 +1935,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
// FIXME: Move to DeclGroup...
|
||||
D.getDeclSpec().getSourceRange().getBegin());
|
||||
}
|
||||
NewFD->setNextDeclarator(LastDeclarator);
|
||||
|
||||
// Set the lexical context. If the declarator has a C++
|
||||
// scope specifier, the lexical context will be different
|
||||
@@ -2517,39 +2514,29 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
|
||||
}
|
||||
}
|
||||
|
||||
/// The declarators are chained together backwards, reverse the list.
|
||||
Sema::DeclPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy group) {
|
||||
// Often we have single declarators, handle them quickly.
|
||||
Decl *Group = group.getAs<Decl>();
|
||||
if (Group == 0)
|
||||
return DeclPtrTy();
|
||||
Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
|
||||
unsigned NumDecls) {
|
||||
llvm::SmallVector<Decl*, 8> Decls;
|
||||
|
||||
for (unsigned i = 0; i != NumDecls; ++i)
|
||||
if (Decl *D = Group[i].getAs<Decl>())
|
||||
Decls.push_back(D);
|
||||
|
||||
Decl *NewGroup = 0;
|
||||
if (Group->getNextDeclarator() == 0)
|
||||
NewGroup = Group;
|
||||
else { // reverse the list.
|
||||
while (Group) {
|
||||
Decl *Next = Group->getNextDeclarator();
|
||||
Group->setNextDeclarator(NewGroup);
|
||||
NewGroup = Group;
|
||||
Group = Next;
|
||||
}
|
||||
}
|
||||
// Perform semantic analysis that depends on having fully processed both
|
||||
// the declarator and initializer.
|
||||
for (Decl *ID = NewGroup; ID; ID = ID->getNextDeclarator()) {
|
||||
VarDecl *IDecl = dyn_cast<VarDecl>(ID);
|
||||
for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
|
||||
VarDecl *IDecl = dyn_cast<VarDecl>(Decls[i]);
|
||||
if (!IDecl)
|
||||
continue;
|
||||
QualType T = IDecl->getType();
|
||||
|
||||
|
||||
// Block scope. C99 6.7p7: If an identifier for an object is declared with
|
||||
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
|
||||
if (IDecl->isBlockVarDecl() &&
|
||||
IDecl->getStorageClass() != VarDecl::Extern) {
|
||||
if (!IDecl->isInvalidDecl() &&
|
||||
RequireCompleteType(IDecl->getLocation(), T,
|
||||
diag::err_typecheck_decl_incomplete_type))
|
||||
diag::err_typecheck_decl_incomplete_type))
|
||||
IDecl->setInvalidDecl();
|
||||
}
|
||||
// File scope. C99 6.9.2p2: A declaration of an identifier for and
|
||||
@@ -2560,13 +2547,13 @@ Sema::DeclPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy group) {
|
||||
if (IDecl->isTentativeDefinition(Context)) {
|
||||
QualType CheckType = T;
|
||||
unsigned DiagID = diag::err_typecheck_decl_incomplete_type;
|
||||
|
||||
|
||||
const IncompleteArrayType *ArrayT = Context.getAsIncompleteArrayType(T);
|
||||
if (ArrayT) {
|
||||
CheckType = ArrayT->getElementType();
|
||||
DiagID = diag::err_illegal_decl_array_incomplete_type;
|
||||
}
|
||||
|
||||
|
||||
if (IDecl->isInvalidDecl()) {
|
||||
// Do nothing with invalid declarations
|
||||
} else if ((ArrayT || IDecl->getStorageClass() == VarDecl::Static) &&
|
||||
@@ -2578,9 +2565,11 @@ Sema::DeclPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy group) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeclPtrTy::make(NewGroup);
|
||||
return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
|
||||
&Decls[0], NumDecls));
|
||||
}
|
||||
|
||||
|
||||
/// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
|
||||
/// to introduce parameters into function prototype scope.
|
||||
Sema::DeclPtrTy
|
||||
@@ -2722,9 +2711,8 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
|
||||
|
||||
Scope *ParentScope = FnBodyScope->getParent();
|
||||
|
||||
return ActOnStartOfFunctionDef(FnBodyScope,
|
||||
ActOnDeclarator(ParentScope, D, DeclPtrTy(),
|
||||
/*IsFunctionDefinition=*/true));
|
||||
DeclPtrTy DP = ActOnDeclarator(ParentScope, D, /*IsFunctionDefinition=*/true);
|
||||
return ActOnStartOfFunctionDef(FnBodyScope, DP);
|
||||
}
|
||||
|
||||
Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
|
||||
@@ -3056,8 +3044,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
|
||||
}
|
||||
}
|
||||
|
||||
TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
|
||||
Decl *LastDeclarator) {
|
||||
TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T) {
|
||||
assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
|
||||
assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
|
||||
|
||||
@@ -3076,7 +3063,6 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
|
||||
TD->setTypedefForAnonDecl(NewTD);
|
||||
}
|
||||
|
||||
NewTD->setNextDeclarator(LastDeclarator);
|
||||
if (D.getInvalidType())
|
||||
NewTD->setInvalidDecl();
|
||||
return NewTD;
|
||||
|
||||
@@ -473,8 +473,7 @@ void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
|
||||
/// declarators on it.
|
||||
Sema::DeclPtrTy
|
||||
Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
|
||||
ExprTy *BW, ExprTy *InitExpr,
|
||||
DeclPtrTy LastInGroup) {
|
||||
ExprTy *BW, ExprTy *InitExpr) {
|
||||
const DeclSpec &DS = D.getDeclSpec();
|
||||
DeclarationName Name = GetNameForDeclarator(D);
|
||||
Expr *BitWidth = static_cast<Expr*>(BW);
|
||||
@@ -553,10 +552,10 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
|
||||
AS);
|
||||
assert(Member && "HandleField never returns null");
|
||||
} else {
|
||||
Member = ActOnDeclarator(S, D, LastInGroup).getAs<Decl>();
|
||||
Member = ActOnDeclarator(S, D).getAs<Decl>();
|
||||
if (!Member) {
|
||||
if (BitWidth) DeleteExpr(BitWidth);
|
||||
return LastInGroup;
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
// Non-instance-fields can't have a bitfield.
|
||||
@@ -595,7 +594,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
|
||||
|
||||
if (isInstField) {
|
||||
FieldCollector->Add(cast<FieldDecl>(Member));
|
||||
return LastInGroup;
|
||||
return DeclPtrTy();
|
||||
}
|
||||
return DeclPtrTy::make(Member);
|
||||
}
|
||||
|
||||
@@ -1234,8 +1234,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
|
||||
void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
|
||||
DeclPtrTy *allMethods, unsigned allNum,
|
||||
DeclPtrTy *allProperties, unsigned pNum,
|
||||
DeclPtrTy *allTUVars,
|
||||
unsigned tuvNum) {
|
||||
DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
|
||||
Decl *ClassDecl = classDecl.getAs<Decl>();
|
||||
|
||||
// FIXME: If we don't have a ClassDecl, we have an error. We should consider
|
||||
@@ -1339,16 +1338,18 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isInterfaceDeclKind)
|
||||
for (unsigned i = 0; i < tuvNum; i++) {
|
||||
if (VarDecl *VDecl = dyn_cast<VarDecl>(allTUVars[i].getAs<Decl>())) {
|
||||
if (VDecl->getStorageClass() != VarDecl::Extern &&
|
||||
VDecl->getStorageClass() != VarDecl::PrivateExtern) {
|
||||
NamedDecl *ClassNameDecl = dyn_cast<NamedDecl>(ClassDecl);
|
||||
Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass)
|
||||
<< ClassNameDecl->getIdentifier();
|
||||
if (isInterfaceDeclKind) {
|
||||
// Reject invalid vardecls.
|
||||
for (unsigned i = 0; i != tuvNum; i++) {
|
||||
DeclGroupRef DG = allTUVars[i].getAsVal<DeclGroupRef>();
|
||||
for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
|
||||
if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
|
||||
if (VDecl->getStorageClass() != VarDecl::Extern &&
|
||||
VDecl->getStorageClass() != VarDecl::PrivateExtern)
|
||||
Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass)
|
||||
<< cast<NamedDecl>(ClassDecl)->getIdentifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,31 +37,13 @@ Sema::OwningStmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
|
||||
return Owned(new (Context) NullStmt(SemiLoc));
|
||||
}
|
||||
|
||||
Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclPtrTy decl,
|
||||
Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
Decl *D = decl.getAs<Decl>();
|
||||
if (D == 0)
|
||||
return StmtError();
|
||||
|
||||
// This is a temporary hack until we are always passing around
|
||||
// DeclGroupRefs.
|
||||
llvm::SmallVector<Decl*, 10> decls;
|
||||
while (D) {
|
||||
Decl* d = D;
|
||||
D = D->getNextDeclarator();
|
||||
d->setNextDeclarator(0);
|
||||
decls.push_back(d);
|
||||
}
|
||||
|
||||
assert (!decls.empty());
|
||||
|
||||
if (decls.size() == 1) {
|
||||
DeclGroupRef DG(*decls.begin());
|
||||
return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
|
||||
}
|
||||
|
||||
DeclGroupRef DG(DeclGroup::Create(Context, decls.size(), &decls[0]));
|
||||
// If we have an invalid decl, just return an error.
|
||||
if (!dg) return StmtError();
|
||||
|
||||
DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
|
||||
return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
|
||||
}
|
||||
|
||||
|
||||
@@ -539,8 +539,9 @@ namespace {
|
||||
public:
|
||||
ASTPrinter(llvm::raw_ostream* o = NULL) : DeclPrinter(o) {}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D) {
|
||||
PrintDecl(D);
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
|
||||
PrintDecl(*I);
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
@@ -562,11 +563,15 @@ namespace {
|
||||
SM = &Context.getSourceManager();
|
||||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D);
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
|
||||
HandleTopLevelSingleDecl(*I);
|
||||
}
|
||||
void HandleTopLevelSingleDecl(Decl *D);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
void ASTDumper::HandleTopLevelDecl(Decl *D) {
|
||||
void ASTDumper::HandleTopLevelSingleDecl(Decl *D) {
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
PrintFunctionDeclStart(FD);
|
||||
|
||||
@@ -624,12 +629,17 @@ namespace {
|
||||
void Initialize(ASTContext &Context) {
|
||||
SM = &Context.getSourceManager();
|
||||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
|
||||
HandleTopLevelSingleDecl(*I);
|
||||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D);
|
||||
void HandleTopLevelSingleDecl(Decl *D);
|
||||
};
|
||||
}
|
||||
|
||||
void ASTViewer::HandleTopLevelDecl(Decl *D) {
|
||||
void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
DeclPrinter().PrintFunctionDeclStart(FD);
|
||||
|
||||
|
||||
@@ -220,7 +220,12 @@ namespace {
|
||||
Ctx = &Context;
|
||||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D);
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
|
||||
HandleTopLevelSingleDecl(*I);
|
||||
}
|
||||
|
||||
void HandleTopLevelSingleDecl(Decl *D);
|
||||
virtual void HandleTranslationUnit(ASTContext &C);
|
||||
|
||||
void HandleCode(Decl* D, Stmt* Body, Actions& actions);
|
||||
@@ -411,7 +416,7 @@ namespace llvm {
|
||||
// AnalysisConsumer implementation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void AnalysisConsumer::HandleTopLevelDecl(Decl *D) {
|
||||
void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
|
||||
switch (D->getKind()) {
|
||||
case Decl::Function: {
|
||||
FunctionDecl* FD = cast<FunctionDecl>(D);
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ASTConsumers.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/CodeGen/ModuleBuilder.h"
|
||||
#include "clang/Frontend/CompileOptions.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/DeclGroup.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/PassManager.h"
|
||||
@@ -117,13 +118,14 @@ namespace {
|
||||
LLVMIRGeneration.stopTimer();
|
||||
}
|
||||
|
||||
virtual void HandleTopLevelDecl(Decl *D) {
|
||||
PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
|
||||
Context->getSourceManager(),
|
||||
"LLVM IR generation of declaration");
|
||||
|
||||
if (CompileOpts.TimePasses)
|
||||
LLVMIRGeneration.startTimer();
|
||||
|
||||
|
||||
Gen->HandleTopLevelDecl(D);
|
||||
|
||||
if (CompileOpts.TimePasses)
|
||||
|
||||
@@ -29,8 +29,7 @@ namespace {
|
||||
/// ActOnDeclarator - This callback is invoked when a declarator is parsed
|
||||
/// and 'Init' specifies the initializer if any. This is for things like:
|
||||
/// "int X = 4" or "typedef int foo".
|
||||
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
|
||||
DeclPtrTy LastInGroup) {
|
||||
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
|
||||
llvm::cout << __FUNCTION__ << " ";
|
||||
if (IdentifierInfo *II = D.getIdentifier()) {
|
||||
llvm::cout << "'" << II->getName() << "'";
|
||||
@@ -40,7 +39,7 @@ namespace {
|
||||
llvm::cout << "\n";
|
||||
|
||||
// Pass up to EmptyActions so that the symbol table is maintained right.
|
||||
return MinimalAction::ActOnDeclarator(S, D, LastInGroup);
|
||||
return MinimalAction::ActOnDeclarator(S, D);
|
||||
}
|
||||
/// ActOnPopScope - This callback is called immediately before the specified
|
||||
/// scope is popped and deleted.
|
||||
@@ -112,17 +111,20 @@ namespace {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
/// FinalizeDeclaratorGroup - After a sequence of declarators are parsed,
|
||||
/// this gives the actions implementation a chance to process the group as
|
||||
/// a whole.
|
||||
virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
|
||||
unsigned NumDecls) {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return DeclPtrTy();
|
||||
return DeclGroupPtrTy();
|
||||
}
|
||||
|
||||
/// ActOnStartOfFunctionDef - This is called at the start of a function
|
||||
/// definition, instead of calling ActOnDeclarator. The Declarator includes
|
||||
/// information about formal arguments that are part of this function.
|
||||
virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
|
||||
virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope,
|
||||
Declarator &D){
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return DeclPtrTy();
|
||||
}
|
||||
@@ -256,7 +258,7 @@ namespace {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return StmtEmpty();
|
||||
}
|
||||
virtual OwningStmtResult ActOnDeclStmt(DeclPtrTy Decl,
|
||||
virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
|
||||
@@ -83,7 +83,11 @@ public:
|
||||
const char *NewStr, unsigned NewLength);
|
||||
|
||||
// Top Level Driver code.
|
||||
virtual void HandleTopLevelDecl(Decl *D);
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
|
||||
HandleTopLevelSingleDecl(*I);
|
||||
}
|
||||
void HandleTopLevelSingleDecl(Decl *D);
|
||||
void HandleDeclInMainFile(Decl *D);
|
||||
|
||||
// Top level
|
||||
@@ -336,7 +340,7 @@ void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
|
||||
// Top Level Driver Code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void RewriteBlocks::HandleTopLevelDecl(Decl *D) {
|
||||
void RewriteBlocks::HandleTopLevelSingleDecl(Decl *D) {
|
||||
// Two cases: either the decl could be in the main file, or it could be in a
|
||||
// #included file. If the former, rewrite it now. If the later, check to see
|
||||
// if we rewrote the #include/#import.
|
||||
|
||||
@@ -126,7 +126,11 @@ namespace {
|
||||
virtual void Initialize(ASTContext &context);
|
||||
|
||||
// Top Level Driver code.
|
||||
virtual void HandleTopLevelDecl(Decl *D);
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D) {
|
||||
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
|
||||
HandleTopLevelSingleDecl(*I);
|
||||
}
|
||||
void HandleTopLevelSingleDecl(Decl *D);
|
||||
void HandleDeclInMainFile(Decl *D);
|
||||
RewriteObjC(std::string inFile, std::string outFile,
|
||||
Diagnostic &D, const LangOptions &LOpts);
|
||||
@@ -550,7 +554,7 @@ void RewriteObjC::Initialize(ASTContext &context) {
|
||||
// Top Level Driver Code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void RewriteObjC::HandleTopLevelDecl(Decl *D) {
|
||||
void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
|
||||
// Two cases: either the decl could be in the main file, or it could be in a
|
||||
// #included file. If the former, rewrite it now. If the later, check to see
|
||||
// if we rewrote the #include/#import.
|
||||
@@ -583,7 +587,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) {
|
||||
for (DeclContext::decl_iterator DI = LSD->decls_begin(),
|
||||
DIEnd = LSD->decls_end();
|
||||
DI != DIEnd; ++DI)
|
||||
HandleTopLevelDecl(*DI);
|
||||
HandleTopLevelSingleDecl(*DI);
|
||||
}
|
||||
// If we have a decl in the main file, see if we should rewrite it.
|
||||
if (SM->isFromMainFile(Loc))
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/CFG.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclGroup.h"
|
||||
#include "clang.h"
|
||||
#include "ASTConsumers.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@@ -73,7 +74,7 @@ bool SerializationTest::Serialize(llvm::sys::Path& Filename,
|
||||
TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl();
|
||||
for (DeclContext::decl_iterator I = TUD->decls_begin(), E =TUD->decls_end();
|
||||
I != E; ++I)
|
||||
FilePrinter->HandleTopLevelDecl(*I);
|
||||
FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I));
|
||||
}
|
||||
|
||||
// Serialize the translation unit.
|
||||
@@ -124,7 +125,7 @@ bool SerializationTest::Deserialize(llvm::sys::Path& Filename,
|
||||
TranslationUnitDecl *TUD = NewCtx->getTranslationUnitDecl();
|
||||
for (DeclContext::decl_iterator I = TUD->decls_begin(), E = TUD->decls_end();
|
||||
I != E; ++I)
|
||||
FilePrinter->HandleTopLevelDecl(*I);
|
||||
FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I));
|
||||
}
|
||||
|
||||
delete NewCtx;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclGroup.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/LexDiagnostic.h"
|
||||
@@ -1563,7 +1564,7 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag,
|
||||
TranslationUnitDecl *TUD = Ctx->getTranslationUnitDecl();
|
||||
for (DeclContext::decl_iterator I = TUD->decls_begin(), E = TUD->decls_end();
|
||||
I != E; ++I)
|
||||
Consumer->HandleTopLevelDecl(*I);
|
||||
Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user