From dfab6cb59a703f2ce4d58371652ce879f4c85a09 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 8 Feb 2008 00:33:21 +0000 Subject: [PATCH] Put back the top-level asm code; all tests pass now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46868 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/Decl.cpp | 7 ++++++- AST/DeclSerialization.cpp | 23 +++++++++++++++++++++++ CodeGen/ModuleBuilder.cpp | 9 +++++++++ Driver/ASTConsumers.cpp | 6 ++++++ Parse/Parser.cpp | 23 ++++++++++++++--------- Sema/Sema.h | 3 ++- Sema/SemaDecl.cpp | 7 +++++++ include/clang/AST/Decl.h | 23 +++++++++++++++++++++++ include/clang/Parse/Action.h | 4 ++++ include/clang/Parse/Parser.h | 2 +- 10 files changed, 95 insertions(+), 12 deletions(-) diff --git a/AST/Decl.cpp b/AST/Decl.cpp index 78916c53b7..55abe6f34d 100644 --- a/AST/Decl.cpp +++ b/AST/Decl.cpp @@ -38,6 +38,7 @@ static unsigned nObjCCategoryImpl = 0; static unsigned nObjCCompatibleAlias = 0; static unsigned nObjCPropertyDecl = 0; static unsigned nLinkageSpecDecl = 0; +static unsigned nFileScopeAsmDecl = 0; static bool StatSwitch = false; @@ -169,7 +170,8 @@ void Decl::PrintStats() { nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+ nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+ nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+ - nLinkageSpecDecl*sizeof(LinkageSpecDecl))); + nLinkageSpecDecl*sizeof(LinkageSpecDecl)+ + nFileScopeAsmDecl*sizeof(FileScopeAsmDecl))); } @@ -240,6 +242,9 @@ void Decl::addDeclKind(const Kind k) { case LinkageSpec: nLinkageSpecDecl++; break; + case FileScopeAsm: + nFileScopeAsmDecl++; + break; } } diff --git a/AST/DeclSerialization.cpp b/AST/DeclSerialization.cpp index 146ebbacbe..cb91846a02 100644 --- a/AST/DeclSerialization.cpp +++ b/AST/DeclSerialization.cpp @@ -67,6 +67,9 @@ Decl* Decl::Create(Deserializer& D) { case Typedef: return TypedefDecl::CreateImpl(D); + + case FileScopeAsm: + return FileScopeAsmDecl::CreateImpl(D); } } @@ -438,3 +441,23 @@ void LinkageSpecDecl::ReadInRec(Deserializer& D) { Language = static_cast(D.ReadInt()); D.ReadPtr(this->D); } + +//===----------------------------------------------------------------------===// +// FileScopeAsm Serialization. +//===----------------------------------------------------------------------===// + +void FileScopeAsmDecl::EmitImpl(llvm::Serializer& S) const +{ + Decl::EmitInRec(S); + S.EmitOwnedPtr(AsmString); +} + +FileScopeAsmDecl* FileScopeAsmDecl::CreateImpl(Deserializer& D) { + FileScopeAsmDecl* decl = new FileScopeAsmDecl(SourceLocation(), 0); + + decl->Decl::ReadInRec(D); + decl->AsmString = cast(D.ReadOwnedPtr()); +// D.ReadOwnedPtr(D.ReadOwnedPtr())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString); + + return decl; +} diff --git a/CodeGen/ModuleBuilder.cpp b/CodeGen/ModuleBuilder.cpp index 50d6fedadd..06467488a5 100644 --- a/CodeGen/ModuleBuilder.cpp +++ b/CodeGen/ModuleBuilder.cpp @@ -70,6 +70,15 @@ namespace { Builder->WarnUnsupported(LSD, "linkage spec"); // FIXME: implement C++ linkage, C linkage works mostly by C // language reuse already. + } else if (FileScopeAsmDecl *AD = dyn_cast(D)) { + std::string AsmString(AD->getAsmString()->getStrData(), + AD->getAsmString()->getByteLength()); + + const std::string &S = Builder->getModule().getModuleInlineAsm(); + if (S.empty()) + Builder->getModule().setModuleInlineAsm(AsmString); + else + Builder->getModule().setModuleInlineAsm(S + '\n' + AsmString); } else { assert(isa(D) && "Unknown top level decl"); // TODO: handle debug info? diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 3868e7d75c..688619438b 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -97,6 +97,10 @@ void DeclPrinter:: PrintDecl(Decl *D) { Out << "Read top-level variable decl: '" << SD->getName() << "'\n"; } else if (LinkageSpecDecl *LSD = dyn_cast(D)) { PrintLinkageSpec(LSD); + } else if (FileScopeAsmDecl *AD = dyn_cast(D)) { + Out << "asm("; + AD->getAsmString()->printPretty(Out); + Out << ")\n"; } else { assert(0 && "Unknown decl type!"); } @@ -402,6 +406,8 @@ namespace { Out << "Read objc fwd protocol decl\n"; } else if (isa(D)) { Out << "Read objc fwd class decl\n"; + } else if (isa(D)) { + Out << "Read file scope asm decl\n"; } else { assert(0 && "Unknown decl type!"); } diff --git a/Parse/Parser.cpp b/Parse/Parser.cpp index 6f2a71257a..e3208a0b3e 100644 --- a/Parse/Parser.cpp +++ b/Parse/Parser.cpp @@ -320,12 +320,15 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() { // FIXME: Restore extension warnings. return RV; } - case tok::kw_asm: - ParseSimpleAsm(); + case tok::kw_asm: { + ExprResult Result = ParseSimpleAsm(); + ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "top-level asm block"); - // TODO: Invoke action for top-level asm. - return 0; + + if (!Result.isInvalid) + return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.Val); + } case tok::at: // @ is not a legal token unless objc is enabled, no need to check. return ParseObjCAtDirectives(); @@ -610,19 +613,21 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() { /// [GNU] simple-asm-expr: /// 'asm' '(' asm-string-literal ')' /// -void Parser::ParseSimpleAsm() { +Parser::ExprResult Parser::ParseSimpleAsm() { assert(Tok.is(tok::kw_asm) && "Not an asm!"); - ConsumeToken(); + SourceLocation Loc = ConsumeToken(); if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after, "asm"); - return; + return 0; } - SourceLocation Loc = ConsumeParen(); + ConsumeParen(); - ParseAsmStringLiteral(); + ExprResult Result = ParseAsmStringLiteral(); MatchRHSPunctuation(tok::r_paren, Loc); + + return Result; } diff --git a/Sema/Sema.h b/Sema/Sema.h index 06a12e4f7f..f3595e1076 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -197,7 +197,8 @@ private: virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace, SourceLocation RBrace, const char *Lang, unsigned StrSize, DeclTy *D); - + virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprTy *expr); + /// Scope actions. virtual void ActOnPopScope(SourceLocation Loc, Scope *S); virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index cd546f3efc..00776912b0 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1711,6 +1711,13 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, Consumer.HandleTagDeclDefinition(Enum); } +Sema::DeclTy *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc, + ExprTy *expr) { + StringLiteral *AsmString = cast((Expr*)expr); + + return new FileScopeAsmDecl(Loc, AsmString); +} + Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace, SourceLocation RBrace, diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index cc96b0732d..07588e4c06 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -27,6 +27,7 @@ class Decl; namespace clang { class Expr; class Stmt; +class StringLiteral; class FunctionDecl; class IdentifierInfo; @@ -71,6 +72,7 @@ public: ObjCClass, ObjCForwardProtocol, LinkageSpec, + FileScopeAsm, // For each non-leaf class, we now define a mapping to the first/last member // of the class, to allow efficient classof. @@ -755,6 +757,27 @@ protected: friend Decl* Decl::Create(llvm::Deserializer& D); }; +class FileScopeAsmDecl : public Decl { + StringLiteral *AsmString; +public: + FileScopeAsmDecl(SourceLocation L, StringLiteral *asmstring) + : Decl(FileScopeAsm, L), AsmString(asmstring) {} + + const StringLiteral *getAsmString() const { return AsmString; } + StringLiteral *getAsmString() { return AsmString; } + static bool classof(const Decl *D) { + return D->getKind() == FileScopeAsm; + } + static bool classof(const FileScopeAsmDecl *D) { return true; } +protected: + /// EmitImpl - Serialize this FileScopeAsmDecl. Called by Decl::Emit. + virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a FileScopeAsmDecl. Called by Decl::Create. + static FileScopeAsmDecl* CreateImpl(llvm::Deserializer& D); + + friend Decl* Decl::Create(llvm::Deserializer& D); +}; /// LinkageSpecDecl - This represents a linkage specification. For example: /// extern "C" void foo(); diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 7a2081978d..003dd9e01b 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -141,6 +141,10 @@ public: return Decl; } + virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprTy *AsmString) { + return 0; + } + /// ActOnPopScope - This callback is called immediately before the specified /// scope is popped and deleted. virtual void ActOnPopScope(SourceLocation Loc, Scope *S) {} diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 2712daa245..1987e964ec 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -256,7 +256,7 @@ private: DeclTy *ParseDeclarationOrFunctionDefinition(); DeclTy *ParseFunctionDefinition(Declarator &D); void ParseKNRParamDeclarations(Declarator &D); - void ParseSimpleAsm(); + ExprResult ParseSimpleAsm(); ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations -- 2.40.0