Handle top-level asm declarations.

llvm-svn: 46855
This commit is contained in:
Anders Carlsson 2008-02-07 17:19:11 +00:00
parent 63a8452e9c
commit bcc3a4bf64
10 changed files with 93 additions and 13 deletions

View File

@ -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;
}
}

View File

@ -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<LanguageIDs>(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<StringLiteral>(D.ReadOwnedPtr<Expr>());
// D.ReadOwnedPtr(D.ReadOwnedPtr<StringLiteral>())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString);
return decl;
}

View File

@ -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<FileScopeAsmDecl>(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<TypeDecl>(D) && "Unknown top level decl");
// TODO: handle debug info?

View File

@ -97,6 +97,10 @@ void DeclPrinter:: PrintDecl(Decl *D) {
Out << "Read top-level variable decl: '" << SD->getName() << "'\n";
} else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
PrintLinkageSpec(LSD);
} else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(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<ObjCClassDecl>(D)) {
Out << "Read objc fwd class decl\n";
} else if (isa<FileScopeAsmDecl>(D)) {
Out << "Read file scope asm decl\n";
} else {
assert(0 && "Unknown decl type!");
}

View File

@ -321,11 +321,7 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
return RV;
}
case tok::kw_asm:
ParseSimpleAsm();
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
"top-level asm block");
// TODO: Invoke action for top-level asm.
return 0;
return ParseSimpleAsm();
case tok::at:
// @ is not a legal token unless objc is enabled, no need to check.
return ParseObjCAtDirectives();
@ -610,19 +606,25 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() {
/// [GNU] simple-asm-expr:
/// 'asm' '(' asm-string-literal ')'
///
void Parser::ParseSimpleAsm() {
Parser::DeclTy *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);
if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
"top-level asm block"))
return 0;
return Actions.ActOnFileScopeAsmDecl(Loc, Result.Val);
}

View File

@ -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);

View File

@ -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<StringLiteral>((Expr*)expr);
return new FileScopeAsmDecl(Loc, AsmString);
}
Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
SourceLocation LBrace,
SourceLocation RBrace,

View File

@ -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();

View File

@ -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) {}

View File

@ -256,7 +256,7 @@ private:
DeclTy *ParseDeclarationOrFunctionDefinition();
DeclTy *ParseFunctionDefinition(Declarator &D);
void ParseKNRParamDeclarations(Declarator &D);
void ParseSimpleAsm();
DeclTy *ParseSimpleAsm();
ExprResult ParseAsmStringLiteral();
// Objective-C External Declarations