[cfe-commits] r39229 - in /cfe/cfe/trunk: AST/SemaDecl.cpp Parse/ParseDecl.cpp Parse/Parser.cpp Sema/SemaDecl.cpp include/clang/Parse/DeclSpec.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:41:35 PDT 2007
Author: sabre
Date: Wed Jul 11 11:41:33 2007
New Revision: 39229
URL: http://llvm.org/viewvc/llvm-project?rev=39229&view=rev
Log:
First step towards accurately retaining information about function
parameters: build an array of ParamInfo structures and pass it to the
declarator for safe keeping (it owns the list).
Next step: actually populate the arg array with useful stuff.
Modified:
cfe/cfe/trunk/AST/SemaDecl.cpp
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/Sema/SemaDecl.cpp
cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39229&r1=39228&r2=39229&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:41:33 2007
@@ -140,7 +140,7 @@
bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
- D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, true, Loc));
+ D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, 0, 0, Loc));
D.SetIdentifier(&II, Loc);
Decl *Result = static_cast<Decl*>(ParseDeclarator(S, D, 0, 0));
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39229&r1=39228&r2=39229&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:33 2007
@@ -264,8 +264,8 @@
CurScope)) {
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
TypeRep);
+ break;
}
- break;
}
// FALL THROUGH.
default:
@@ -862,6 +862,7 @@
/// identifier
/// identifier-list ',' identifier
///
+#include <iostream>
void Parser::ParseParenDeclarator(Declarator &D) {
SourceLocation StartLoc = ConsumeParen();
@@ -912,14 +913,15 @@
// identifier list of a K&R-style function.
bool IsVariadic;
bool HasPrototype;
- bool IsEmpty = false;
bool ErrorEmitted = false;
+ // Build up an array of information about the parsed arguments.
+ SmallVector<DeclaratorTypeInfo::ParamInfo, 16> ParamInfo;
+
if (Tok.getKind() == tok::r_paren) {
// int() -> no prototype, no '...'.
IsVariadic = false;
HasPrototype = false;
- IsEmpty = true;
} else if (Tok.getKind() == tok::identifier &&
// K&R identifier lists can't have typedefs as identifiers, per
// C99 6.7.5.3p11.
@@ -935,6 +937,9 @@
if (!D.getIdentifier())
Diag(Tok, diag::ext_ident_list_in_param);
+ // FIXME: pass stuff.
+ ParamInfo.push_back(DeclaratorTypeInfo::ParamInfo());
+
// TODO: Remember token.
ConsumeToken();
while (Tok.getKind() == tok::comma) {
@@ -945,6 +950,9 @@
ErrorEmitted = true;
break;
}
+
+ // FIXME: pass stuff.
+ ParamInfo.push_back(DeclaratorTypeInfo::ParamInfo());
}
// K&R 'prototype'.
@@ -1010,6 +1018,10 @@
DS.ClearStorageClassSpecs();
}
+
+ // FIXME: pass stuff.
+ ParamInfo.push_back(DeclaratorTypeInfo::ParamInfo());
+
// Inform the actions module about the parameter declarator, so it gets
// added to the current scope.
Actions.ParseDeclarator(CurScope, DeclaratorInfo, 0, 0);
@@ -1027,11 +1039,16 @@
ExitScope();
}
- // TODO: capture argument info.
+ DeclaratorTypeInfo::ParamInfo *ParamArray = 0;
+ if (!ParamInfo.empty()) {
+ ParamArray = new DeclaratorTypeInfo::ParamInfo[ParamInfo.size()];
+ memcpy(ParamArray, &ParamInfo[0], sizeof(ParamInfo[0])*ParamInfo.size());
+ }
// Remember that we parsed a function type, and remember the attributes.
D.AddTypeInfo(DeclaratorTypeInfo::getFunction(HasPrototype, IsVariadic,
- IsEmpty, StartLoc));
+ ParamInfo.size(), ParamArray,
+ StartLoc));
// If we have the closing ')', eat it and we're done.
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=39229&r1=39228&r2=39229&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:41:33 2007
@@ -413,7 +413,7 @@
// If this declaration was formed with a K&R-style identifier list for the
// arguments, parse declarations for all of the args next.
// int foo(a,b) int a; float b; {}
- if (!FnTypeInfo.Fun.hasPrototype && !FnTypeInfo.Fun.isEmpty) {
+ if (!FnTypeInfo.Fun.hasPrototype && FnTypeInfo.Fun.NumArgs != 0) {
// Read all the argument declarations.
while (isDeclarationSpecifier())
ParseDeclaration(Declarator::KNRTypeListContext);
Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39229&r1=39228&r2=39229&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:41:33 2007
@@ -140,7 +140,7 @@
bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy);
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
- D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, true, Loc));
+ D.AddTypeInfo(DeclaratorTypeInfo::getFunction(false, false, 0, 0, Loc));
D.SetIdentifier(&II, Loc);
Decl *Result = static_cast<Decl*>(ParseDeclarator(S, D, 0, 0));
Modified: cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=39229&r1=39228&r2=39229&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:41:33 2007
@@ -215,7 +215,7 @@
/// Finish - This does final analysis of the declspec, issuing diagnostics for
/// things like "_Imaginary" (lacking an FP type). After calling this method,
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
- void Finish(Diagnostic &D,const LangOptions &Lang);
+ void Finish(Diagnostic &D, const LangOptions &Lang);
};
@@ -249,6 +249,20 @@
/// FIXME: make this be an expression* when we have expressions.
void *NumElts;
};
+
+ /// ParamInfo - An array of paraminfo objects is allocated whenever a function
+ /// declarator is parsed. There are two interesting styles of arguments here:
+ /// K&R-style identifier lists and parameter type lists. K&R-style identifier
+ /// lists will have information about the identifier, but no type information.
+ /// Parameter type lists will have type info (if the actions module provides
+ /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
+ struct ParamInfo {
+ /// Ident - In a K&R
+ IdentifierInfo *Ident;
+ SourceLocation IdentLoc;
+ void *TypeInfo;
+ };
+
struct FunctionTypeInfo {
/// hasPrototype - This is true if the function had at least one typed
/// argument. If the function is () or (a,b,c), then it has no prototype,
@@ -258,8 +272,15 @@
/// isVariadic - If this function has a prototype, and if that proto ends
/// with ',...)', this is true.
bool isVariadic : 1;
- // TODO: capture argument info.
- bool isEmpty : 1;
+
+ /// NumArgs - This is the number of formal arguments provided for the
+ /// declarator.
+ unsigned NumArgs;
+
+ /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
+ /// describe the arguments for this function declarator. This is null if
+ /// there are no arguments specified.
+ ParamInfo *ArgInfo;
};
union {
@@ -294,17 +315,18 @@
return I;
}
- /// getFunction - Return a DeclaratorTypeInfo for a function.
- ///
+ /// getFunction - Return a DeclaratorTypeInfo for a function. ArgInfo should
+ /// be a new[]'d array with NumArgs elements in it, or null if NumArgs is 0.
static DeclaratorTypeInfo getFunction(bool hasProto, bool isVariadic,
- bool isEmpty /*fixme arg info*/,
+ unsigned NumArgs, ParamInfo *ArgInfo,
SourceLocation Loc) {
DeclaratorTypeInfo I;
I.Kind = Function;
I.Loc = Loc;
I.Fun.hasPrototype = hasProto;
I.Fun.isVariadic = isVariadic;
- I.Fun.isEmpty = isEmpty;
+ I.Fun.NumArgs = NumArgs;
+ I.Fun.ArgInfo = ArgInfo;
return I;
}
};
@@ -350,15 +372,26 @@
Declarator(const DeclSpec &ds, TheContext C)
: DS(ds), Identifier(0), Context(C) {
}
+
+ ~Declarator() {
+ clear();
+ }
/// getDeclSpec - Return the declaration-specifier that this declarator was
/// declared with.
const DeclSpec &getDeclSpec() const { return DS; }
+ TheContext getContext() const { return Context; }
+
/// clear - Reset the contents of this Declarator.
void clear() {
Identifier = 0;
IdentifierLoc = SourceLocation();
+
+ for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
+ if (DeclTypeInfo[i].Kind == DeclaratorTypeInfo::Function)
+ delete [] DeclTypeInfo[i].Fun.ArgInfo;
+
DeclTypeInfo.clear();
}
More information about the cfe-commits
mailing list