summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/DeclSpec.cpp38
-rw-r--r--clang/lib/Parse/ParseDecl.cpp6
-rw-r--r--clang/lib/Parse/ParseExpr.cpp3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
4 files changed, 44 insertions, 5 deletions
diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp
index 4459c804f37..83bf36c7163 100644
--- a/clang/lib/Parse/DeclSpec.cpp
+++ b/clang/lib/Parse/DeclSpec.cpp
@@ -14,6 +14,7 @@
#include "clang/Parse/DeclSpec.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/STLExtras.h"
using namespace clang;
@@ -23,6 +24,43 @@ static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
}
+/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+/// "TheDeclarator" is the declarator that this will be added to.
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+ ParamInfo *ArgInfo,
+ unsigned NumArgs,
+ unsigned TypeQuals,
+ SourceLocation Loc,
+ Declarator &TheDeclarator) {
+ DeclaratorChunk I;
+ I.Kind = Function;
+ I.Loc = Loc;
+ I.Fun.hasPrototype = hasProto;
+ I.Fun.isVariadic = isVariadic;
+ I.Fun.DeleteArgInfo = false;
+ I.Fun.TypeQuals = TypeQuals;
+ I.Fun.NumArgs = NumArgs;
+ I.Fun.ArgInfo = 0;
+
+ // new[] an argument array if needed.
+ if (NumArgs) {
+ // If the 'InlineParams' in Declarator is unused and big enough, put our
+ // parameter list there (in an effort to avoid new/delete traffic). If it
+ // is already used (consider a function returning a function pointer) or too
+ // small (function taking too many arguments), go to the heap.
+ if (!TheDeclarator.InlineParamsUsed &&
+ NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
+ I.Fun.ArgInfo = TheDeclarator.InlineParams;
+ I.Fun.DeleteArgInfo = false;
+ TheDeclarator.InlineParamsUsed = true;
+ } else {
+ I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
+ I.Fun.DeleteArgInfo = true;
+ }
+ memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
+ }
+ return I;
+}
/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
///
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 456acbeebdf..bf922780c7c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1854,7 +1854,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
/*variadic*/ false,
/*arglist*/ 0, 0,
DS.getTypeQualifiers(),
- LParenLoc));
+ LParenLoc, D));
return;
}
@@ -2013,7 +2013,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
&ParamInfo[0], ParamInfo.size(),
DS.getTypeQualifiers(),
- LParenLoc));
+ LParenLoc, D));
}
/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
@@ -2080,7 +2080,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
// has no prototype.
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
&ParamInfo[0], ParamInfo.size(),
- /*TypeQuals*/0, LParenLoc));
+ /*TypeQuals*/0, LParenLoc, D));
// If we have the closing ')', eat it and we're done.
MatchRHSPunctuation(tok::r_paren, LParenLoc);
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index dc95c381d5c..38518557a3f 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1222,7 +1222,8 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
} else {
// Otherwise, pretend we saw (void).
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
- 0, 0, 0, CaretLoc));
+ 0, 0, 0, CaretLoc,
+ ParamInfo));
}
// Inform sema that we are starting a block.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6f731ca5480..c91d174d654 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2772,7 +2772,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
Error = Error; // Silence warning.
assert(!Error && "Error setting up implicit decl!");
Declarator D(DS, Declarator::BlockContext);
- D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, 0, Loc));
+ D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, 0, Loc, D));
D.SetIdentifier(&II, Loc);
// Insert this function into translation-unit scope.
OpenPOWER on IntegriCloud