diff --git a/clang/AST/Decl.cpp b/clang/AST/Decl.cpp new file mode 100644 index 000000000000..a3760ebc4d61 --- /dev/null +++ b/clang/AST/Decl.cpp @@ -0,0 +1,15 @@ +//===--- Decl.cpp - Declaration AST Node Implementation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the Decl class and subclasses. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/Decl.h" + diff --git a/clang/AST/Sema.cpp b/clang/AST/Sema.cpp index 81f4b45dbd4c..6788496cb98d 100644 --- a/clang/AST/Sema.cpp +++ b/clang/AST/Sema.cpp @@ -100,7 +100,7 @@ public: bool ASTBuilder::isTypedefName(const IdentifierInfo &II, Scope *S) const { Decl *D = II.getFETokenInfo(); - return D != 0 && D->getDeclSpecs().StorageClassSpec == DeclSpec::SCS_typedef; + return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef; } void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D, @@ -108,7 +108,11 @@ void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D, IdentifierInfo *II = D.getIdentifier(); Decl *PrevDecl = II ? II->getFETokenInfo() : 0; - Decl *New = new Decl(II, D.getDeclSpec(), Loc, PrevDecl); + Decl *New; + if (D.isFunctionDeclarator()) + New = new FunctionDecl(II, D, Loc, PrevDecl); + else + New = new VarDecl(II, D, Loc, PrevDecl); // If this has an identifier, add it to the scope stack. if (II) { @@ -208,10 +212,11 @@ Action::ExprResult ASTBuilder::ParseUnaryOp(const LexerToken &Tok, case tok::minus: Opc = UnaryOperator::Minus; break; case tok::tilde: Opc = UnaryOperator::Not; break; case tok::exclaim: Opc = UnaryOperator::LNot; break; - case tok::kw___real: Opc = UnaryOperator::Real; break; - case tok::kw___imag: Opc = UnaryOperator::Imag; break; case tok::kw_sizeof: Opc = UnaryOperator::SizeOf; break; case tok::kw___alignof: Opc = UnaryOperator::AlignOf; break; + case tok::kw___real: Opc = UnaryOperator::Real; break; + case tok::kw___imag: Opc = UnaryOperator::Imag; break; + case tok::ampamp: Opc = UnaryOperator::AddrLabel; break; } if (!FullLocInfo) diff --git a/clang/Parse/ParseDecl.cpp b/clang/Parse/ParseDecl.cpp index da1e455a9a87..121963ab08cb 100644 --- a/clang/Parse/ParseDecl.cpp +++ b/clang/Parse/ParseDecl.cpp @@ -136,6 +136,7 @@ void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) { } // Inform the current actions module that we just parsed a declarator. + // TODO: pass asm & attributes. Actions.ParseDeclarator(Tok.getLocation(), CurScope, D, Init.Val); // If we don't have a comma, it is either the end of the list (a ';') or an diff --git a/clang/Parse/Parser.cpp b/clang/Parse/Parser.cpp index 2ba501565d7a..d4710fb991fb 100644 --- a/clang/Parse/Parser.cpp +++ b/clang/Parse/Parser.cpp @@ -338,13 +338,13 @@ void Parser::ParseDeclarationOrFunctionDefinition() { Tok.getKind() == tok::kw_asm || // int X() __asm__ -> not a fn def Tok.getKind() == tok::kw___attribute) {// int X() __attr__ -> not a fn def // FALL THROUGH. - } else if (DeclaratorInfo.isInnermostFunctionType() && + } else if (DeclaratorInfo.isFunctionDeclarator() && (Tok.getKind() == tok::l_brace || // int X() {} isDeclarationSpecifier())) { // int X(f) int f; {} ParseFunctionDefinition(DeclaratorInfo); return; } else { - if (DeclaratorInfo.isInnermostFunctionType()) + if (DeclaratorInfo.isFunctionDeclarator()) Diag(Tok, diag::err_expected_fn_body); else Diag(Tok, diag::err_expected_after_declarator); diff --git a/clang/Sema/Sema.cpp b/clang/Sema/Sema.cpp index 81f4b45dbd4c..6788496cb98d 100644 --- a/clang/Sema/Sema.cpp +++ b/clang/Sema/Sema.cpp @@ -100,7 +100,7 @@ public: bool ASTBuilder::isTypedefName(const IdentifierInfo &II, Scope *S) const { Decl *D = II.getFETokenInfo(); - return D != 0 && D->getDeclSpecs().StorageClassSpec == DeclSpec::SCS_typedef; + return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef; } void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D, @@ -108,7 +108,11 @@ void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D, IdentifierInfo *II = D.getIdentifier(); Decl *PrevDecl = II ? II->getFETokenInfo() : 0; - Decl *New = new Decl(II, D.getDeclSpec(), Loc, PrevDecl); + Decl *New; + if (D.isFunctionDeclarator()) + New = new FunctionDecl(II, D, Loc, PrevDecl); + else + New = new VarDecl(II, D, Loc, PrevDecl); // If this has an identifier, add it to the scope stack. if (II) { @@ -208,10 +212,11 @@ Action::ExprResult ASTBuilder::ParseUnaryOp(const LexerToken &Tok, case tok::minus: Opc = UnaryOperator::Minus; break; case tok::tilde: Opc = UnaryOperator::Not; break; case tok::exclaim: Opc = UnaryOperator::LNot; break; - case tok::kw___real: Opc = UnaryOperator::Real; break; - case tok::kw___imag: Opc = UnaryOperator::Imag; break; case tok::kw_sizeof: Opc = UnaryOperator::SizeOf; break; case tok::kw___alignof: Opc = UnaryOperator::AlignOf; break; + case tok::kw___real: Opc = UnaryOperator::Real; break; + case tok::kw___imag: Opc = UnaryOperator::Imag; break; + case tok::ampamp: Opc = UnaryOperator::AddrLabel; break; } if (!FullLocInfo) diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 6709a924e1d4..f5d778ef7bc6 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ DEC8DAC00A94402500353FCA /* ASTStreamer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8DABF0A94402500353FCA /* ASTStreamer.h */; }; DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; }; DED627030AE0C51D001E80A4 /* Targets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED627020AE0C51D001E80A4 /* Targets.cpp */; }; + DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */; }; DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; }; DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; }; DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; }; @@ -141,6 +142,7 @@ DEC8DABF0A94402500353FCA /* ASTStreamer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASTStreamer.h; path = clang/AST/ASTStreamer.h; sourceTree = ""; }; DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = ""; }; DED627020AE0C51D001E80A4 /* Targets.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Targets.cpp; path = Driver/Targets.cpp; sourceTree = ""; }; + DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Decl.cpp; path = AST/Decl.cpp; sourceTree = SOURCE_ROOT; }; DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = ""; }; DED7D7320A524295003AD0FB /* DiagnosticKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = DiagnosticKinds.def; sourceTree = ""; }; DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = ""; }; @@ -229,6 +231,7 @@ children = ( DE06E8130A8FF9330050E87E /* Action.h */, DE1F24810A7DCD3800FBF588 /* Declarations.h */, + DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */, DE1F22020A7D852A00FBF588 /* Parser.h */, DE06BECA0A854E4B0050E87E /* Scope.h */, ); @@ -427,6 +430,7 @@ DE5932D40AD60FF400BC794C /* PrintPreprocessedOutput.cpp in Sources */, DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */, DED627030AE0C51D001E80A4 /* Targets.cpp in Sources */, + DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 822a35e75ee4..7928ff9f2660 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -44,16 +44,34 @@ class Decl { /// Decl *Next; public: - Decl(IdentifierInfo *Id, const DeclSpec &DS, SourceLocation loc, Decl *next) - : Identifier(Id), DeclarationSpecifier(DS), Loc(loc), Next(next) {} - + Decl(IdentifierInfo *Id, const Declarator &D, SourceLocation loc, Decl *next) + : Identifier(Id), DeclarationSpecifier(D.getDeclSpec()), Loc(loc), + Next(next) {} const IdentifierInfo *getIdentifier() const { return Identifier; } - const DeclSpec &getDeclSpecs() const { return DeclarationSpecifier; } + const DeclSpec &getDeclSpec() const { return DeclarationSpecifier; } Decl *getNext() const { return Next; } - +}; + +/// FunctionDecl - An instance of this class is created to represent a function +/// declaration or definition. +class FunctionDecl : public Decl { + // Args etc. +public: + FunctionDecl(IdentifierInfo *Id, const Declarator &D, + SourceLocation Loc, Decl *Next) : Decl(Id, D, Loc, Next) {} + +}; + +/// VarDecl - An instance of this class is created to represent a variable +/// declaration or definition. +class VarDecl : public Decl { + // Initializer. +public: + VarDecl(IdentifierInfo *Id, const Declarator &D, + SourceLocation Loc, Decl *Next) : Decl(Id, D, Loc, Next) {} }; diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index 2eea1381fa1a..89a9c2ea165c 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -318,9 +318,9 @@ public: return DeclTypeInfo[i]; } - /// isInnermostFunctionType - Once this declarator is fully parsed and formed, + /// isFunctionDeclarator - Once this declarator is fully parsed and formed, /// this method returns true if the identifier is a function declarator. - bool isInnermostFunctionType() const { + bool isFunctionDeclarator() const { return !DeclTypeInfo.empty() && DeclTypeInfo[0].Kind == DeclaratorTypeInfo::Function; }