forked from OSchip/llvm-project
Finally break down and chain together decls that are defined with common declspecs,
like: int X, Y, Z; This is required for the code gen to get to all of the declarations in a DeclStmt, and should simplify some other code. llvm-svn: 39623
This commit is contained in:
parent
d9d2fb1420
commit
776fac8703
|
@ -124,9 +124,11 @@ void StmtPrinter::VisitNullStmt(NullStmt *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
|
void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
|
||||||
Indent();
|
for (Decl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
|
||||||
PrintRawDecl(Node->getDecl());
|
Indent();
|
||||||
OS << ";\n";
|
PrintRawDecl(D);
|
||||||
|
OS << ";\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
|
void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
|
||||||
|
|
|
@ -279,15 +279,15 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||||
|
|
||||||
if (Tok.getKind() == tok::semi) {
|
if (Tok.getKind() == tok::semi) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return LastDeclInGroup;
|
return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
|
||||||
} else {
|
|
||||||
Diag(Tok, diag::err_parse_error);
|
|
||||||
// Skip to end of block or statement
|
|
||||||
SkipUntil(tok::r_brace, true);
|
|
||||||
if (Tok.getKind() == tok::semi)
|
|
||||||
ConsumeToken();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Diag(Tok, diag::err_parse_error);
|
||||||
|
// Skip to end of block or statement
|
||||||
|
SkipUntil(tok::r_brace, true);
|
||||||
|
if (Tok.getKind() == tok::semi)
|
||||||
|
ConsumeToken();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseSpecifierQualifierList
|
/// ParseSpecifierQualifierList
|
||||||
|
|
|
@ -98,6 +98,8 @@ private:
|
||||||
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
|
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
|
||||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
DeclTy *LastInGroup);
|
DeclTy *LastInGroup);
|
||||||
|
virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
|
||||||
|
|
||||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
||||||
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
||||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
virtual void PopScope(SourceLocation Loc, Scope *S);
|
||||||
|
@ -120,7 +122,7 @@ private:
|
||||||
DeclTy **Elements, unsigned NumElements);
|
DeclTy **Elements, unsigned NumElements);
|
||||||
private:
|
private:
|
||||||
/// Subroutines of ParseDeclarator()...
|
/// Subroutines of ParseDeclarator()...
|
||||||
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D);
|
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, Decl *LastDeclarator);
|
||||||
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
||||||
FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
|
FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
|
||||||
VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
|
VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
|
||||||
|
|
|
@ -155,7 +155,8 @@ Decl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S) {
|
||||||
Builtin::ID BID = (Builtin::ID)bid;
|
Builtin::ID BID = (Builtin::ID)bid;
|
||||||
|
|
||||||
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
|
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
|
||||||
FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R);
|
FunctionDecl *New = new FunctionDecl(SourceLocation(), II, R,
|
||||||
|
FunctionDecl::Extern, 0);
|
||||||
|
|
||||||
// Find translation-unit scope to insert this function into.
|
// Find translation-unit scope to insert this function into.
|
||||||
while (S->getParent())
|
while (S->getParent())
|
||||||
|
@ -270,20 +271,21 @@ Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Action::DeclTy *
|
Sema::DeclTy *
|
||||||
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
DeclTy *LastInGroup) {
|
DeclTy *lastDeclarator) {
|
||||||
|
Decl *LastDeclarator = (Decl*)lastDeclarator;
|
||||||
IdentifierInfo *II = D.getIdentifier();
|
IdentifierInfo *II = D.getIdentifier();
|
||||||
|
|
||||||
// See if this is a redefinition of a variable in the same scope.
|
// See if this is a redefinition of a variable in the same scope.
|
||||||
Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
|
Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
|
||||||
D.getIdentifierLoc(), S);
|
D.getIdentifierLoc(), S);
|
||||||
if (!S->isDeclScope(PrevDecl))
|
if (PrevDecl && !S->isDeclScope(PrevDecl))
|
||||||
PrevDecl = 0; // If in outer scope, it isn't the same thing.
|
PrevDecl = 0; // If in outer scope, it isn't the same thing.
|
||||||
|
|
||||||
Decl *New;
|
Decl *New;
|
||||||
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
||||||
TypedefDecl *NewTD = ParseTypedefDecl(S, D);
|
TypedefDecl *NewTD = ParseTypedefDecl(S, D, LastDeclarator);
|
||||||
if (!NewTD) return 0;
|
if (!NewTD) return 0;
|
||||||
|
|
||||||
// Merge the decl with the existing one if appropriate.
|
// Merge the decl with the existing one if appropriate.
|
||||||
|
@ -317,7 +319,8 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
|
case DeclSpec::SCS_static: SC = FunctionDecl::Static; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC);
|
FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC,
|
||||||
|
LastDeclarator);
|
||||||
|
|
||||||
// Merge the decl with the existing one if appropriate.
|
// Merge the decl with the existing one if appropriate.
|
||||||
if (PrevDecl) {
|
if (PrevDecl) {
|
||||||
|
@ -368,7 +371,7 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
if (VerifyConstantArrayType(ary, D.getIdentifierLoc()))
|
if (VerifyConstantArrayType(ary, D.getIdentifierLoc()))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC);
|
NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
|
||||||
} else {
|
} else {
|
||||||
// Block scope. C99 6.7p7: If an identifier for an object is declared with
|
// 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...
|
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
|
||||||
|
@ -387,7 +390,7 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC);
|
NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
|
||||||
}
|
}
|
||||||
// Merge the decl with the existing one if appropriate.
|
// Merge the decl with the existing one if appropriate.
|
||||||
if (PrevDecl) {
|
if (PrevDecl) {
|
||||||
|
@ -406,11 +409,27 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S->getParent() == 0)
|
if (S->getParent() == 0)
|
||||||
AddTopLevelDecl(New, (Decl *)LastInGroup);
|
AddTopLevelDecl(New, LastDeclarator);
|
||||||
|
|
||||||
return New;
|
return New;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The declarators are chained together backwards, reverse the list.
|
||||||
|
Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
|
||||||
|
// Often we have single declarators, handle them quickly.
|
||||||
|
Decl *Group = static_cast<Decl*>(group);
|
||||||
|
if (Group->getNextDeclarator() == 0) return Group;
|
||||||
|
|
||||||
|
Decl *NewGroup = 0;
|
||||||
|
while (Group) {
|
||||||
|
Decl *Next = Group->getNextDeclarator();
|
||||||
|
Group->setNextDeclarator(NewGroup);
|
||||||
|
NewGroup = Group;
|
||||||
|
Group = Next;
|
||||||
|
}
|
||||||
|
return NewGroup;
|
||||||
|
}
|
||||||
|
|
||||||
VarDecl *
|
VarDecl *
|
||||||
Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||||
Scope *FnScope) {
|
Scope *FnScope) {
|
||||||
|
@ -426,9 +445,10 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Handle storage class (auto, register). No declarator?
|
// FIXME: Handle storage class (auto, register). No declarator?
|
||||||
|
// TODO: Chain to previous parameter with the prevdeclarator chain?
|
||||||
VarDecl *New = new ParmVarDecl(PI.IdentLoc, II,
|
VarDecl *New = new ParmVarDecl(PI.IdentLoc, II,
|
||||||
QualType::getFromOpaquePtr(PI.TypeInfo),
|
QualType::getFromOpaquePtr(PI.TypeInfo),
|
||||||
VarDecl::None);
|
VarDecl::None, 0);
|
||||||
|
|
||||||
// If this has an identifier, add it to the scope stack.
|
// If this has an identifier, add it to the scope stack.
|
||||||
if (II) {
|
if (II) {
|
||||||
|
@ -556,14 +576,16 @@ Decl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
|
TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D,
|
||||||
assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
|
Decl *LastDeclarator) {
|
||||||
|
assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
|
||||||
|
|
||||||
QualType T = GetTypeForDeclarator(D, S);
|
QualType T = GetTypeForDeclarator(D, S);
|
||||||
if (T.isNull()) return 0;
|
if (T.isNull()) return 0;
|
||||||
|
|
||||||
// Scope manipulation handled by caller.
|
// Scope manipulation handled by caller.
|
||||||
return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T);
|
return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T,
|
||||||
|
LastDeclarator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -638,14 +660,18 @@ Sema::DeclTy *Sema::ParseTag(Scope *S, unsigned TagType, TagKind TK,
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
default: assert(0 && "Unknown tag kind!");
|
default: assert(0 && "Unknown tag kind!");
|
||||||
case Decl::Enum:
|
case Decl::Enum:
|
||||||
New = new EnumDecl(Loc, Name);
|
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
|
||||||
|
// enum X { A, B, C } D; D should chain to X.
|
||||||
|
New = new EnumDecl(Loc, Name, 0);
|
||||||
// If this is an undefined enum, warn.
|
// If this is an undefined enum, warn.
|
||||||
if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
|
if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
|
||||||
break;
|
break;
|
||||||
case Decl::Union:
|
case Decl::Union:
|
||||||
case Decl::Struct:
|
case Decl::Struct:
|
||||||
case Decl::Class:
|
case Decl::Class:
|
||||||
New = new RecordDecl(Kind, Loc, Name);
|
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
|
||||||
|
// struct X { int A; } D; D should chain to X.
|
||||||
|
New = new RecordDecl(Kind, Loc, Name, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +723,9 @@ Sema::DeclTy *Sema::ParseField(Scope *S, DeclTy *TagDecl,
|
||||||
if (VerifyConstantArrayType(ary, Loc))
|
if (VerifyConstantArrayType(ary, Loc))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return new FieldDecl(Loc, II, T);
|
|
||||||
|
// FIXME: Chain fielddecls together.
|
||||||
|
return new FieldDecl(Loc, II, T, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
|
void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
|
||||||
|
@ -837,7 +865,8 @@ Sema::DeclTy *Sema::ParseEnumConstant(Scope *S, DeclTy *EnumDeclX,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
QualType Ty = Context.getTagDeclType(TheEnumDecl);
|
QualType Ty = Context.getTagDeclType(TheEnumDecl);
|
||||||
EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val);
|
// FIXME: Chain EnumConstantDecl's together.
|
||||||
|
EnumConstantDecl *New = new EnumConstantDecl(IdLoc, Id, Ty, (Expr *)Val, 0);
|
||||||
|
|
||||||
// Register this decl in the current scope stack.
|
// Register this decl in the current scope stack.
|
||||||
New->setNext(Id->getFETokenInfo<Decl>());
|
New->setNext(Id->getFETokenInfo<Decl>());
|
||||||
|
@ -869,9 +898,8 @@ void Sema::AddTopLevelDecl(Decl *current, Decl *last) {
|
||||||
|
|
||||||
// If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
|
// If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
|
||||||
// remember this in the LastInGroupList list.
|
// remember this in the LastInGroupList list.
|
||||||
if (last) {
|
if (last)
|
||||||
LastInGroupList.push_back((Decl*)last);
|
LastInGroupList.push_back((Decl*)last);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseAttribute GCC __attribute__
|
/// ParseAttribute GCC __attribute__
|
||||||
|
|
|
@ -64,9 +64,13 @@ private:
|
||||||
///
|
///
|
||||||
Decl *Next;
|
Decl *Next;
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Decl(Kind DK, SourceLocation L, IdentifierInfo *Id)
|
Decl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *NextDecl)
|
||||||
: DeclKind(DK), Loc(L), Identifier(Id), Next(0) {
|
: DeclKind(DK), Loc(L), Identifier(Id), Next(0), NextDeclarator(NextDecl) {
|
||||||
if (Decl::CollectingStats()) addDeclKind(DK);
|
if (Decl::CollectingStats()) addDeclKind(DK);
|
||||||
}
|
}
|
||||||
virtual ~Decl();
|
virtual ~Decl();
|
||||||
|
@ -81,6 +85,13 @@ public:
|
||||||
Decl *getNext() const { return Next; }
|
Decl *getNext() const { return Next; }
|
||||||
void setNext(Decl *N) { Next = N; }
|
void setNext(Decl *N) { Next = N; }
|
||||||
|
|
||||||
|
/// 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; }
|
||||||
|
|
||||||
IdentifierNamespace getIdentifierNamespace() const {
|
IdentifierNamespace getIdentifierNamespace() const {
|
||||||
switch (DeclKind) {
|
switch (DeclKind) {
|
||||||
default: assert(0 && "Unknown decl kind!");
|
default: assert(0 && "Unknown decl kind!");
|
||||||
|
@ -113,8 +124,8 @@ public:
|
||||||
class ValueDecl : public Decl {
|
class ValueDecl : public Decl {
|
||||||
QualType DeclType;
|
QualType DeclType;
|
||||||
protected:
|
protected:
|
||||||
ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T):
|
ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
|
||||||
Decl(DK, L, Id), DeclType(T) {}
|
Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
|
||||||
public:
|
public:
|
||||||
QualType getType() const { return DeclType; }
|
QualType getType() const { return DeclType; }
|
||||||
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
|
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
|
||||||
|
@ -142,8 +153,8 @@ public:
|
||||||
static bool classof(const VarDecl *D) { return true; }
|
static bool classof(const VarDecl *D) { return true; }
|
||||||
protected:
|
protected:
|
||||||
VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
|
VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
|
||||||
StorageClass SC)
|
StorageClass SC, Decl *PrevDecl)
|
||||||
: ValueDecl(DK, L, Id, T) { SClass = SC; }
|
: ValueDecl(DK, L, Id, T, PrevDecl) { SClass = SC; }
|
||||||
private:
|
private:
|
||||||
StorageClass SClass;
|
StorageClass SClass;
|
||||||
// TODO: Initializer.
|
// TODO: Initializer.
|
||||||
|
@ -152,8 +163,9 @@ private:
|
||||||
/// BlockVarDecl - Represent a local variable declaration.
|
/// BlockVarDecl - Represent a local variable declaration.
|
||||||
class BlockVarDecl : public VarDecl {
|
class BlockVarDecl : public VarDecl {
|
||||||
public:
|
public:
|
||||||
BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S)
|
BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
|
||||||
: VarDecl(BlockVariable, L, Id, T, S) {}
|
Decl *PrevDecl)
|
||||||
|
: VarDecl(BlockVariable, L, Id, T, S, PrevDecl) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
|
static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
|
||||||
|
@ -166,8 +178,9 @@ public:
|
||||||
/// pointer to the decl's scope, which is transient).
|
/// pointer to the decl's scope, which is transient).
|
||||||
class FileVarDecl : public VarDecl {
|
class FileVarDecl : public VarDecl {
|
||||||
public:
|
public:
|
||||||
FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S)
|
FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
|
||||||
: VarDecl(FileVariable, L, Id, T, S) {}
|
Decl *PrevDecl)
|
||||||
|
: VarDecl(FileVariable, L, Id, T, S, PrevDecl) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
static bool classof(const Decl *D) { return D->getKind() == FileVariable; }
|
static bool classof(const Decl *D) { return D->getKind() == FileVariable; }
|
||||||
|
@ -177,8 +190,9 @@ public:
|
||||||
/// ParmVarDecl - Represent a parameter to a function.
|
/// ParmVarDecl - Represent a parameter to a function.
|
||||||
class ParmVarDecl : public VarDecl {
|
class ParmVarDecl : public VarDecl {
|
||||||
public:
|
public:
|
||||||
ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S)
|
ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
|
||||||
: VarDecl(ParmVariable, L, Id, T, S) {}
|
Decl *PrevDecl)
|
||||||
|
: VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
|
static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
|
||||||
|
@ -192,8 +206,9 @@ public:
|
||||||
enum StorageClass {
|
enum StorageClass {
|
||||||
None, Extern, Static
|
None, Extern, Static
|
||||||
};
|
};
|
||||||
FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S=None)
|
FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
|
||||||
: ValueDecl(Function, L, Id, T),
|
StorageClass S = None, Decl *PrevDecl)
|
||||||
|
: ValueDecl(Function, L, Id, T, PrevDecl),
|
||||||
ParamInfo(0), Body(0), DeclChain(0), SClass(S) {}
|
ParamInfo(0), Body(0), DeclChain(0), SClass(S) {}
|
||||||
virtual ~FunctionDecl();
|
virtual ~FunctionDecl();
|
||||||
|
|
||||||
|
@ -240,8 +255,8 @@ private:
|
||||||
class FieldDecl : public Decl {
|
class FieldDecl : public Decl {
|
||||||
QualType DeclType;
|
QualType DeclType;
|
||||||
public:
|
public:
|
||||||
FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
|
FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
|
||||||
: Decl(Field, L, Id), DeclType(T) {}
|
: Decl(Field, L, Id, PrevDecl), DeclType(T) {}
|
||||||
|
|
||||||
QualType getType() const { return DeclType; }
|
QualType getType() const { return DeclType; }
|
||||||
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
|
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
|
||||||
|
@ -260,8 +275,9 @@ public:
|
||||||
class EnumConstantDecl : public ValueDecl {
|
class EnumConstantDecl : public ValueDecl {
|
||||||
Expr *Init; // an integer constant expression
|
Expr *Init; // an integer constant expression
|
||||||
public:
|
public:
|
||||||
EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E)
|
EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
|
||||||
: ValueDecl(EnumConstant, L, Id, T), Init(E) {}
|
Decl *PrevDecl)
|
||||||
|
: ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
static bool classof(const Decl *D) {
|
static bool classof(const Decl *D) {
|
||||||
|
@ -280,8 +296,8 @@ class TypeDecl : public Decl {
|
||||||
Type *TypeForDecl;
|
Type *TypeForDecl;
|
||||||
friend class ASTContext;
|
friend class ASTContext;
|
||||||
protected:
|
protected:
|
||||||
TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
|
TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
|
||||||
: Decl(DK, L, Id), TypeForDecl(0) {}
|
: Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
|
@ -296,8 +312,8 @@ class TypedefDecl : public TypeDecl {
|
||||||
/// UnderlyingType - This is the type the typedef is set to.
|
/// UnderlyingType - This is the type the typedef is set to.
|
||||||
QualType UnderlyingType;
|
QualType UnderlyingType;
|
||||||
public:
|
public:
|
||||||
TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
|
TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
|
||||||
: TypeDecl(Typedef, L, Id), UnderlyingType(T) {}
|
: TypeDecl(Typedef, L, Id, PrevDecl), UnderlyingType(T) {}
|
||||||
|
|
||||||
QualType getUnderlyingType() const { return UnderlyingType; }
|
QualType getUnderlyingType() const { return UnderlyingType; }
|
||||||
|
|
||||||
|
@ -313,7 +329,8 @@ class TagDecl : public TypeDecl {
|
||||||
/// it is a declaration ("struct foo;").
|
/// it is a declaration ("struct foo;").
|
||||||
bool IsDefinition : 1;
|
bool IsDefinition : 1;
|
||||||
protected:
|
protected:
|
||||||
TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id) : TypeDecl(DK, L, Id) {
|
TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
|
||||||
|
: TypeDecl(DK, L, Id, PrevDecl) {
|
||||||
IsDefinition = false;
|
IsDefinition = false;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
@ -351,7 +368,8 @@ class EnumDecl : public TagDecl {
|
||||||
EnumConstantDecl **Elements; // Null if not defined.
|
EnumConstantDecl **Elements; // Null if not defined.
|
||||||
int NumElements; // -1 if not defined.
|
int NumElements; // -1 if not defined.
|
||||||
public:
|
public:
|
||||||
EnumDecl(SourceLocation L, IdentifierInfo *Id) : TagDecl(Enum, L, Id) {
|
EnumDecl(SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
|
||||||
|
: TagDecl(Enum, L, Id, PrevDecl) {
|
||||||
Elements = 0;
|
Elements = 0;
|
||||||
NumElements = -1;
|
NumElements = -1;
|
||||||
}
|
}
|
||||||
|
@ -379,7 +397,8 @@ class RecordDecl : public TagDecl {
|
||||||
FieldDecl **Members; // Null if not defined.
|
FieldDecl **Members; // Null if not defined.
|
||||||
int NumMembers; // -1 if not defined.
|
int NumMembers; // -1 if not defined.
|
||||||
public:
|
public:
|
||||||
RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id) :TagDecl(DK, L, Id){
|
RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
|
||||||
|
: TagDecl(DK, L, Id, PrevDecl) {
|
||||||
HasFlexibleArrayMember = false;
|
HasFlexibleArrayMember = false;
|
||||||
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
|
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
|
||||||
Members = 0;
|
Members = 0;
|
||||||
|
|
|
@ -98,6 +98,12 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
|
||||||
|
/// gives the actions implementation a chance to process the group as a whole.
|
||||||
|
virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
|
||||||
|
return Group;
|
||||||
|
}
|
||||||
|
|
||||||
/// ParseStartOfFunctionDef - This is called at the start of a function
|
/// ParseStartOfFunctionDef - This is called at the start of a function
|
||||||
/// definition, instead of calling ParseDeclarator. The Declarator includes
|
/// definition, instead of calling ParseDeclarator. The Declarator includes
|
||||||
/// information about formal arguments that are part of this function.
|
/// information about formal arguments that are part of this function.
|
||||||
|
|
Loading…
Reference in New Issue