[cfe-commits] r68997 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHReader.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp test/PCH/functions.c test/PCH/functions.h
Douglas Gregor
dgregor at apple.com
Mon Apr 13 15:18:37 PDT 2009
Author: dgregor
Date: Mon Apr 13 17:18:37 2009
New Revision: 68997
URL: http://llvm.org/viewvc/llvm-project?rev=68997&view=rev
Log:
PCH support for functions and their parameters.
Added:
cfe/trunk/test/PCH/functions.c
cfe/trunk/test/PCH/functions.h
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Frontend/PCHBitCodes.h
cfe/trunk/include/clang/Frontend/PCHReader.h
cfe/trunk/lib/Frontend/PCHReader.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=68997&r1=68996&r2=68997&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Apr 13 17:18:37 2009
@@ -510,10 +510,12 @@
Expr *DefArg)
: ParmVarDecl(OriginalParmVar, DC, L, Id, T, S, DefArg), OriginalType(OT) {}
public:
- static OriginalParmVarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,IdentifierInfo *Id,
- QualType T, QualType OT,
- StorageClass S, Expr *DefArg);
+ static OriginalParmVarDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,IdentifierInfo *Id,
+ QualType T, QualType OT,
+ StorageClass S, Expr *DefArg);
+
+ void setOriginalType(QualType T) { OriginalType = T; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == OriginalParmVar; }
@@ -603,6 +605,7 @@
SourceLocation TSStartLoc = SourceLocation());
SourceLocation getTypeSpecStartLoc() const { return TypeSpecStartLoc; }
+ void setTypeSpecStartLoc(SourceLocation TS) { TypeSpecStartLoc = TS; }
/// getBody - Retrieve the body (definition) of the function. The
/// function body might be in any of the (re-)declarations of this
@@ -629,23 +632,24 @@
/// Whether this function is virtual, either by explicit marking, or by
/// overriding a virtual function. Only valid on C++ member functions.
bool isVirtual() { return IsVirtual; }
- void setVirtual() { IsVirtual = true; }
+ void setVirtual(bool V = true) { IsVirtual = V; }
/// Whether this virtual function is pure, i.e. makes the containing class
/// abstract.
bool isPure() const { return IsPure; }
- void setPure() { IsPure = true; }
+ void setPure(bool P = true) { IsPure = P; }
/// \brief Whether this function has a prototype, either because one
/// was explicitly written or because it was "inherited" by merging
/// a declaration without a prototype with a declaration that has a
/// prototype.
bool hasPrototype() const { return HasPrototype || InheritedPrototype; }
+ void setHasPrototype(bool P) { HasPrototype = P; }
/// \brief Whether this function inherited its prototype from a
/// previous declaration.
bool inheritedPrototype() const { return InheritedPrototype; }
- void setInheritedPrototype() { InheritedPrototype = true; }
+ void setInheritedPrototype(bool P = true) { InheritedPrototype = P; }
/// \brief Whether this function has been deleted.
///
@@ -666,7 +670,7 @@
/// };
/// @endcode
bool isDeleted() const { return IsDeleted; }
- void setDeleted() { IsDeleted = true; }
+ void setDeleted(bool D = true) { IsDeleted = D; }
/// \brief Determines whether this is a function "main", which is
/// the entry point into an executable program.
@@ -726,6 +730,7 @@
void setStorageClass(StorageClass SC) { SClass = SC; }
bool isInline() const { return IsInline; }
+ void setInline(bool I) { IsInline = I; }
/// isOverloadedOperator - Whether this function declaration
/// represents an C++ overloaded operator, e.g., "operator+".
Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=68997&r1=68996&r2=68997&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Mon Apr 13 17:18:37 2009
@@ -320,10 +320,16 @@
DECL_RECORD,
/// \brief An EnumConstantDecl record.
DECL_ENUM_CONSTANT,
+ /// \brief A FunctionDecl record.
+ DECL_FUNCTION,
/// \brief A FieldDecl record.
DECL_FIELD,
/// \brief A VarDecl record.
DECL_VAR,
+ /// \brief A ParmVarDecl record.
+ DECL_PARM_VAR,
+ /// \brief An OriginalParmVarDecl record.
+ DECL_ORIGINAL_PARM_VAR,
/// \brief A record that stores the set of declarations that are
/// lexically stored within a given DeclContext.
///
Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=68997&r1=68996&r2=68997&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Mon Apr 13 17:18:37 2009
@@ -209,6 +209,10 @@
/// \brief Read a signed integral value
llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
+
+ /// \brief Retrieve the AST context that this PCH reader
+ /// supplements.
+ ASTContext &getContext() { return Context; }
};
} // end namespace clang
Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=68997&r1=68996&r2=68997&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Mon Apr 13 17:18:37 2009
@@ -53,8 +53,11 @@
void VisitRecordDecl(RecordDecl *RD);
void VisitValueDecl(ValueDecl *VD);
void VisitEnumConstantDecl(EnumConstantDecl *ECD);
+ void VisitFunctionDecl(FunctionDecl *FD);
void VisitFieldDecl(FieldDecl *FD);
void VisitVarDecl(VarDecl *VD);
+ void VisitParmVarDecl(ParmVarDecl *PD);
+ void VisitOriginalParmVarDecl(OriginalParmVarDecl *PD);
std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
};
@@ -125,6 +128,27 @@
ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
}
+void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
+ VisitValueDecl(FD);
+ // FIXME: function body
+ FD->setPreviousDeclaration(
+ cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
+ FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
+ FD->setInline(Record[Idx++]);
+ FD->setVirtual(Record[Idx++]);
+ FD->setPure(Record[Idx++]);
+ FD->setInheritedPrototype(Record[Idx++]);
+ FD->setHasPrototype(Record[Idx++]);
+ FD->setDeleted(Record[Idx++]);
+ FD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ unsigned NumParams = Record[Idx++];
+ llvm::SmallVector<ParmVarDecl *, 16> Params;
+ Params.reserve(NumParams);
+ for (unsigned I = 0; I != NumParams; ++I)
+ Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+ FD->setParams(Reader.getContext(), &Params[0], NumParams);
+}
+
void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
VisitValueDecl(FD);
FD->setMutable(Record[Idx++]);
@@ -142,6 +166,17 @@
VD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
+void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
+ VisitVarDecl(PD);
+ PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+ // FIXME: default argument
+}
+
+void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) {
+ VisitParmVarDecl(PD);
+ PD->setOriginalType(Reader.GetType(Record[Idx++]));
+}
+
std::pair<uint64_t, uint64_t>
PCHDeclReader::VisitDeclContext(DeclContext *DC) {
uint64_t LexicalOffset = Record[Idx++];
@@ -1021,6 +1056,16 @@
D = ECD;
break;
}
+
+ case pch::DECL_FUNCTION: {
+ FunctionDecl *Function = FunctionDecl::Create(Context, 0, SourceLocation(),
+ DeclarationName(),
+ QualType());
+ LoadedDecl(Index, Function);
+ Reader.VisitFunctionDecl(Function);
+ D = Function;
+ break;
+ }
case pch::DECL_FIELD: {
FieldDecl *Field = FieldDecl::Create(Context, 0, SourceLocation(), 0,
@@ -1040,6 +1085,26 @@
break;
}
+ case pch::DECL_PARM_VAR: {
+ ParmVarDecl *Parm = ParmVarDecl::Create(Context, 0, SourceLocation(), 0,
+ QualType(), VarDecl::None, 0);
+ LoadedDecl(Index, Parm);
+ Reader.VisitParmVarDecl(Parm);
+ D = Parm;
+ break;
+ }
+
+ case pch::DECL_ORIGINAL_PARM_VAR: {
+ OriginalParmVarDecl *Parm
+ = OriginalParmVarDecl::Create(Context, 0, SourceLocation(), 0,
+ QualType(), QualType(), VarDecl::None,
+ 0);
+ LoadedDecl(Index, Parm);
+ Reader.VisitOriginalParmVarDecl(Parm);
+ D = Parm;
+ break;
+ }
+
default:
assert(false && "Cannot de-serialize this kind of declaration");
break;
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=68997&r1=68996&r2=68997&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Apr 13 17:18:37 2009
@@ -257,8 +257,11 @@
void VisitRecordDecl(RecordDecl *D);
void VisitValueDecl(ValueDecl *D);
void VisitEnumConstantDecl(EnumConstantDecl *D);
+ void VisitFunctionDecl(FunctionDecl *D);
void VisitFieldDecl(FieldDecl *D);
void VisitVarDecl(VarDecl *D);
+ void VisitParmVarDecl(ParmVarDecl *D);
+ void VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
uint64_t VisibleOffset);
};
@@ -327,6 +330,25 @@
Code = pch::DECL_ENUM_CONSTANT;
}
+void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
+ VisitValueDecl(D);
+ // FIXME: function body
+ Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+ Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+ Record.push_back(D->isInline());
+ Record.push_back(D->isVirtual());
+ Record.push_back(D->isPure());
+ Record.push_back(D->inheritedPrototype());
+ Record.push_back(D->hasPrototype() && !D->inheritedPrototype());
+ Record.push_back(D->isDeleted());
+ Writer.AddSourceLocation(D->getTypeSpecStartLoc(), Record);
+ Record.push_back(D->param_size());
+ for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
+ P != PEnd; ++P)
+ Writer.AddDeclRef(*P, Record);
+ Code = pch::DECL_FUNCTION;
+}
+
void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {
VisitValueDecl(D);
Record.push_back(D->isMutable());
@@ -336,7 +358,7 @@
void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
VisitValueDecl(D);
- Record.push_back(D->getStorageClass());
+ Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->isThreadSpecified());
Record.push_back(D->hasCXXDirectInitializer());
Record.push_back(D->isDeclaredInCondition());
@@ -346,6 +368,21 @@
Code = pch::DECL_VAR;
}
+void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
+ VisitVarDecl(D);
+ Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
+ // FIXME: emit default argument
+ // FIXME: why isn't the "default argument" just stored as the initializer
+ // in VarDecl?
+ Code = pch::DECL_PARM_VAR;
+}
+
+void PCHDeclWriter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
+ VisitParmVarDecl(D);
+ Writer.AddTypeRef(D->getOriginalType(), Record);
+ Code = pch::DECL_ORIGINAL_PARM_VAR;
+}
+
/// \brief Emit the DeclContext part of a declaration context decl.
///
/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
Added: cfe/trunk/test/PCH/functions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/functions.c?rev=68997&view=auto
==============================================================================
--- cfe/trunk/test/PCH/functions.c (added)
+++ cfe/trunk/test/PCH/functions.c Mon Apr 13 17:18:37 2009
@@ -0,0 +1,20 @@
+// Test this without pch.
+// RUN: clang-cc -include %S/functions.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: clang-cc -emit-pch -o %t %S/functions.h &&
+// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s
+
+int f0(int x0, int y0, ...) { return x0 + y0; }
+
+float *test_f1(int val, double x, double y) {
+ if (val > 5)
+ return f1(x, y);
+ else
+ return f1(x); // expected-error{{too few arguments to function call}}
+}
+
+void test_g0(int *x, float * y) {
+ g0(y); // expected-warning{{incompatible pointer types passing 'float *', expected 'int *'}}
+ g0(x);
+}
Added: cfe/trunk/test/PCH/functions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/functions.h?rev=68997&view=auto
==============================================================================
--- cfe/trunk/test/PCH/functions.h (added)
+++ cfe/trunk/test/PCH/functions.h Mon Apr 13 17:18:37 2009
@@ -0,0 +1,6 @@
+/* For use with the functions.c test */
+
+int f0(int x, int y, ...);
+float *f1(float x, float y);
+
+void g0(int *);
More information about the cfe-commits
mailing list