[cfe-commits] r45904 - in /cfe/trunk: AST/Decl.cpp AST/DeclSerialization.cpp CodeGen/CodeGenModule.cpp CodeGen/CodeGenModule.h CodeGen/ModuleBuilder.cpp Driver/ASTConsumers.cpp Parse/ParseDeclCXX.cpp Parse/Parser.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def include/clang/CodeGen/ModuleBuilder.h include/clang/Parse/Action.h include/clang/Parse/Parser.h
Chris Lattner
sabre at nondot.org
Fri Jan 11 23:05:38 PST 2008
Author: lattner
Date: Sat Jan 12 01:05:38 2008
New Revision: 45904
URL: http://llvm.org/viewvc/llvm-project?rev=45904&view=rev
Log:
Add first pieces of support for parsing and representing
extern "C" in C++ mode. Patch by Mike Stump!
Modified:
cfe/trunk/AST/Decl.cpp
cfe/trunk/AST/DeclSerialization.cpp
cfe/trunk/CodeGen/CodeGenModule.cpp
cfe/trunk/CodeGen/CodeGenModule.h
cfe/trunk/CodeGen/ModuleBuilder.cpp
cfe/trunk/Driver/ASTConsumers.cpp
cfe/trunk/Parse/ParseDeclCXX.cpp
cfe/trunk/Parse/Parser.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Sat Jan 12 01:05:38 2008
@@ -37,6 +37,7 @@
static unsigned nObjCCategoryImpl = 0;
static unsigned nObjCCompatibleAlias = 0;
static unsigned nObjCPropertyDecl = 0;
+static unsigned nLinkageSpecDecl = 0;
static bool StatSwitch = false;
@@ -156,7 +157,9 @@
nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
- nTypedef*sizeof(TypedefDecl)) /* FIXME: add ObjC decls */);
+ nTypedef*sizeof(TypedefDecl)+
+ nLinkageSpecDecl*sizeof(LinkageSpecDecl))
+ /* FIXME: add ObjC decls */);
}
void Decl::addDeclKind(const Kind k) {
@@ -223,6 +226,9 @@
case PropertyDecl:
nObjCPropertyDecl++;
break;
+ case LinkageSpec:
+ nLinkageSpecDecl++;
+ break;
}
}
Modified: cfe/trunk/AST/DeclSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/DeclSerialization.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/AST/DeclSerialization.cpp (original)
+++ cfe/trunk/AST/DeclSerialization.cpp Sat Jan 12 01:05:38 2008
@@ -422,3 +422,19 @@
return decl;
}
+
+//===----------------------------------------------------------------------===//
+// LinkageSpec Serialization.
+//===----------------------------------------------------------------------===//
+
+void LinkageSpecDecl::EmitInRec(Serializer& S) const {
+ Decl::EmitInRec(S);
+ S.EmitInt(getLanguage());
+ S.EmitPtr(D);
+}
+
+void LinkageSpecDecl::ReadInRec(Deserializer& D) {
+ Decl::ReadInRec(D);
+ Language = static_cast<LanguageIDs>(D.ReadInt());
+ D.ReadPtr(this->D);
+}
Modified: cfe/trunk/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenModule.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenModule.cpp Sat Jan 12 01:05:38 2008
@@ -44,6 +44,16 @@
&Msg, 1, &Range, 1);
}
+/// WarnUnsupported - Print out a warning that codegen doesn't support the
+/// specified decl yet.
+void CodeGenModule::WarnUnsupported(const Decl *D, const char *Type) {
+ unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
+ "cannot codegen this %0 yet");
+ std::string Msg = Type;
+ getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID,
+ &Msg, 1);
+}
+
/// ReplaceMapValuesWith - This is a really slow and bad function that
/// searches for any entries in GlobalDeclMap that point to OldVal, changing
/// them to point to NewVal. This is badbadbad, FIXME!
Modified: cfe/trunk/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenModule.h?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/CodeGen/CodeGenModule.h Sat Jan 12 01:05:38 2008
@@ -95,6 +95,10 @@
/// specified stmt yet.
void WarnUnsupported(const Stmt *S, const char *Type);
+ /// WarnUnsupported - Print out a warning that codegen doesn't support the
+ /// specified decl yet.
+ void WarnUnsupported(const Decl *D, const char *Type);
+
private:
/// ReplaceMapValuesWith - This is a really slow and bad function that
/// searches for any entries in GlobalDeclMap that point to OldVal, changing
Modified: cfe/trunk/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/ModuleBuilder.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/CodeGen/ModuleBuilder.cpp Sat Jan 12 01:05:38 2008
@@ -13,6 +13,7 @@
#include "clang/CodeGen/ModuleBuilder.h"
#include "CodeGenModule.h"
+#include "clang/AST/Decl.h"
using namespace clang;
@@ -34,6 +35,16 @@
B->EmitFunction(D);
}
+/// CodeGenLinkageSpec - Emit the specified linkage space to LLVM.
+void clang::CodeGen::CodeGenLinkageSpec(CodeGenModule *Builder,
+ LinkageSpecDecl *LS) {
+ if (LS->getLanguage() == LinkageSpecDecl::lang_cxx)
+ Builder->WarnUnsupported(LS, "linkage spec");
+
+ // FIXME: implement C++ linkage, C linkage works mostly by C
+ // language reuse already.
+}
+
/// CodeGenGlobalVar - Emit the specified global variable to LLVM.
void clang::CodeGen::CodeGenGlobalVar(CodeGenModule *Builder, FileVarDecl *D) {
Builder->EmitGlobalVarDeclarator(D);
Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Sat Jan 12 01:05:38 2008
@@ -39,6 +39,7 @@
void PrintDecl(Decl *D);
void PrintFunctionDeclStart(FunctionDecl *FD);
void PrintTypeDefDecl(TypedefDecl *TD);
+ void PrintLinkageSpec(LinkageSpecDecl *LS);
void PrintObjCMethodDecl(ObjCMethodDecl *OMD);
void PrintObjCImplementationDecl(ObjCImplementationDecl *OID);
void PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID);
@@ -94,6 +95,8 @@
Out << "Read top-level tag decl: '" << TD->getName() << "'\n";
} else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
Out << "Read top-level variable decl: '" << SD->getName() << "'\n";
+ } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+ PrintLinkageSpec(LSD);
} else {
assert(0 && "Unknown decl type!");
}
@@ -152,6 +155,18 @@
Out << "typedef " << S << ";\n";
}
+void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
+ const char *l;
+ if (LS->getLanguage() == LinkageSpecDecl::lang_c)
+ l = "C";
+ else if (LS->getLanguage() == LinkageSpecDecl::lang_cxx)
+ l = "C++";
+ else assert(0 && "unknown language in linkage specification");
+ Out << "extern \"" << l << "\" { ";
+ PrintDecl(LS->getDecl());
+ Out << "}\n";
+}
+
void DeclPrinter::PrintObjCMethodDecl(ObjCMethodDecl *OMD) {
if (OMD->isInstance())
Out << "\n- ";
@@ -608,6 +623,8 @@
CodeGen::CodeGenFunction(Builder, FD);
} else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
CodeGen::CodeGenGlobalVar(Builder, FVD);
+ } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+ CodeGen::CodeGenLinkageSpec(Builder, LSD);
} else {
assert(isa<TypeDecl>(D) && "Only expected type decls here");
// don't codegen for now, eventually pass down for debug info.
Modified: cfe/trunk/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseDeclCXX.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/Parse/ParseDeclCXX.cpp Sat Jan 12 01:05:38 2008
@@ -80,3 +80,40 @@
return 0;
}
+
+/// ParseLinkage - We know that the current token is a string_literal
+/// and just before that, that extern was seen.
+///
+/// linkage-specification: [C++ 7.5p2: dcl.link]
+/// 'extern' string-literal '{' declaration-seq[opt] '}'
+/// 'extern' string-literal declaration
+///
+Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
+ assert(Tok.is(tok::string_literal) && "Not a stringliteral!");
+ llvm::SmallVector<char, 8> LangBuffer;
+ // LangBuffer is guaranteed to be big enough.
+ LangBuffer.resize(Tok.getLength());
+ const char *LangBufPtr = &LangBuffer[0];
+ unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
+
+ SourceLocation Loc = ConsumeStringToken();
+ DeclTy *D = 0;
+ SourceLocation LBrace, RBrace;
+
+ if (Tok.isNot(tok::l_brace)) {
+ D = ParseDeclaration(Context);
+ } else {
+ LBrace = ConsumeBrace();
+ while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ // FIXME capture the decls.
+ D = ParseExternalDeclaration();
+ }
+
+ RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
+ }
+
+ if (!D)
+ return 0;
+
+ return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize, D);
+}
Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Sat Jan 12 01:05:38 2008
@@ -386,6 +386,15 @@
return ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
}
+ // If the declspec consisted only of 'extern' and we have a string
+ // literal following it, this must be a C++ linkage specifier like
+ // 'extern "C"'.
+ // FIXME: This should be limited to just C++/ObjectiveC++
+ if (Tok.is(tok::string_literal) &&
+ DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
+ DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier)
+ return ParseLinkage(Declarator::FileContext);
+
// Parse the first declarator.
Declarator DeclaratorInfo(DS, Declarator::FileContext);
ParseDeclarator(DeclaratorInfo);
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sat Jan 12 01:05:38 2008
@@ -192,6 +192,9 @@
virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body);
+ virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
+ SourceLocation RBrace, const char *Lang,
+ unsigned StrSize, DeclTy *D);
/// Scope actions.
virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Sat Jan 12 01:05:38 2008
@@ -1615,6 +1615,27 @@
Enum->defineElements(EltList, BestType);
}
+Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
+ SourceLocation LBrace,
+ SourceLocation RBrace,
+ const char *Lang,
+ unsigned StrSize,
+ DeclTy *D) {
+ LinkageSpecDecl::LanguageIDs Language;
+ Decl *dcl = static_cast<Decl *>(D);
+ if (strncmp(Lang, "\"C\"", StrSize) == 0)
+ Language = LinkageSpecDecl::lang_c;
+ else if (strncmp(Lang, "\"C++\"", StrSize) == 0)
+ Language = LinkageSpecDecl::lang_cxx;
+ else {
+ Diag(Loc, diag::err_bad_language);
+ return 0;
+ }
+
+ // FIXME: Add all the various semantics of linkage specifications
+ return new LinkageSpecDecl(Loc, Language, dcl);
+}
+
void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) {
const char *attrName = rawAttr->getAttributeName()->getName();
unsigned attrLen = rawAttr->getAttributeName()->getLength();
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Jan 12 01:05:38 2008
@@ -70,6 +70,7 @@
ObjCMethod,
ObjCClass,
ObjCForwardProtocol,
+ LinkageSpec,
// For each non-leaf class, we now define a mapping to the first/last member
// of the class, to allow efficient classof.
@@ -753,6 +754,42 @@
friend Decl* Decl::Create(llvm::Deserializer& D);
};
+
+/// LinkageSpecDecl - This represents a linkage specification. For example:
+/// extern "C" void foo();
+///
+class LinkageSpecDecl : public Decl {
+public:
+ /// LanguageIDs - Used to represent the language in a linkage
+ /// specification. The values are part of the serialization abi for
+ /// ASTs and cannot be changed without altering that abi. To help
+ /// ensure a stable abi for this, we choose the DW_LANG_ encodings
+ /// from the dwarf standard.
+ enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
+ lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
+private:
+ /// Language - The language for this linkage specification.
+ LanguageIDs Language;
+ /// D - This is the Decl of the linkage specification.
+ Decl *D;
+public:
+ LinkageSpecDecl(SourceLocation L, LanguageIDs lang, Decl *d)
+ : Decl(LinkageSpec, L), Language(lang), D(d) {}
+
+ LanguageIDs getLanguage() const { return Language; }
+ const Decl *getDecl() const { return D; }
+ Decl *getDecl() { return D; }
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == LinkageSpec;
+ }
+ static bool classof(const LinkageSpecDecl *D) { return true; }
+
+protected:
+ void EmitInRec(llvm::Serializer& S) const;
+ void ReadInRec(llvm::Deserializer& D);
+};
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Jan 12 01:05:38 2008
@@ -537,6 +537,8 @@
"'%0' qualifier may not be applied to a reference")
DIAG(err_declarator_need_ident, ERROR,
"declarator requires an identifier")
+DIAG(err_bad_language, ERROR,
+ "unknown linkage language")
// Attributes
DIAG(err_attribute_wrong_number_arguments, ERROR,
Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
+++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Sat Jan 12 01:05:38 2008
@@ -22,6 +22,7 @@
namespace clang {
class ASTContext;
class FunctionDecl;
+ class LinkageSpecDecl;
class FileVarDecl;
struct LangOptions;
class Diagnostic;
@@ -37,6 +38,8 @@
/// CodeGenFunction - Convert the AST node for a FunctionDecl into LLVM.
///
void CodeGenFunction(CodeGenModule *Builder, FunctionDecl *D);
+
+ void CodeGenLinkageSpec(CodeGenModule *Builder, LinkageSpecDecl *LS);
/// CodeGenGlobalVar - Emit the specified global variable to LLVM.
void CodeGenGlobalVar(CodeGenModule *Builder, FileVarDecl *D);
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sat Jan 12 01:05:38 2008
@@ -154,6 +154,12 @@
virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
return 0;
}
+
+ virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
+ SourceLocation RBrace, const char *Lang,
+ unsigned StrSize, DeclTy *D) {
+ return 0;
+ }
//===--------------------------------------------------------------------===//
// Type Parsing Callbacks.
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=45904&r1=45903&r2=45904&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Jan 12 01:05:38 2008
@@ -437,6 +437,7 @@
// C++ 7: Declarations [dcl.dcl]
DeclTy *ParseNamespace(unsigned Context);
+ DeclTy *ParseLinkage(unsigned Context);
};
More information about the cfe-commits
mailing list